1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.content.ContextWrapper; 22 import android.content.Intent; 23 import android.os.Bundle; 24 import android.os.DropBoxManager; 25 import android.os.Looper; 26 import android.os.Parcel; 27 import android.os.ParcelFileDescriptor; 28 import android.os.Parcelable; 29 import android.os.Process; 30 import android.os.StatFs; 31 import android.os.UserHandle; 32 import android.provider.Settings; 33 import android.test.AndroidTestCase; 34 35 import com.android.server.DropBoxManagerInternal.EntrySource; 36 import com.android.server.DropBoxManagerService.EntryFile; 37 38 import libcore.io.Streams; 39 40 import java.io.BufferedReader; 41 import java.io.File; 42 import java.io.FileDescriptor; 43 import java.io.FileOutputStream; 44 import java.io.FileWriter; 45 import java.io.IOException; 46 import java.io.InputStream; 47 import java.io.InputStreamReader; 48 import java.nio.charset.StandardCharsets; 49 import java.util.Random; 50 import java.util.zip.GZIPOutputStream; 51 52 /** 53 * Test {@link DropBoxManager} functionality. 54 * 55 * Run with: 56 * bit FrameworksServicesTests:com.android.server.DropBoxTest 57 */ 58 public class DropBoxTest extends AndroidTestCase { 59 private Context mContext; 60 61 @Override setUp()62 protected void setUp() throws Exception { 63 super.setUp(); 64 65 LocalServices.removeServiceForTest(DropBoxManagerInternal.class); 66 67 mContext = new ContextWrapper(super.getContext()) { 68 @Override 69 public void sendBroadcastAsUser(Intent intent, 70 UserHandle user, String receiverPermission, Bundle options) { 71 // Don't actually send broadcasts. 72 } 73 }; 74 } 75 tearDown()76 public void tearDown() throws Exception { 77 ContentResolver cr = getContext().getContentResolver(); 78 Settings.Global.putString(cr, Settings.Global.DROPBOX_AGE_SECONDS, ""); 79 Settings.Global.putString(cr, Settings.Global.DROPBOX_MAX_FILES, ""); 80 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, ""); 81 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", ""); 82 } 83 84 @Override getContext()85 public Context getContext() { 86 return mContext; 87 } 88 testAddText()89 public void testAddText() throws Exception { 90 File dir = getEmptyDir("testAddText"); 91 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 92 Looper.getMainLooper()); 93 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 94 95 long before = System.currentTimeMillis(); 96 Thread.sleep(5); 97 dropbox.addText("DropBoxTest", "TEST0"); 98 Thread.sleep(5); 99 long between = System.currentTimeMillis(); 100 Thread.sleep(5); 101 dropbox.addText("DropBoxTest", "TEST1"); 102 dropbox.addText("DropBoxTest", "TEST2"); 103 Thread.sleep(5); 104 long after = System.currentTimeMillis(); 105 106 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 107 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 108 DropBoxManager.Entry e2 = dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis()); 109 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e2.getTimeMillis())); 110 111 assertTrue(e0.getTimeMillis() > before); 112 assertTrue(e0.getTimeMillis() < between); 113 assertTrue(e1.getTimeMillis() > between); 114 assertTrue(e1.getTimeMillis() < e2.getTimeMillis()); 115 assertTrue(e2.getTimeMillis() < after); 116 117 assertEquals("TEST0", e0.getText(80)); 118 assertEquals("TEST1", e1.getText(80)); 119 assertEquals("TES", e2.getText(3)); 120 121 e0.close(); 122 e1.close(); 123 e2.close(); 124 } 125 126 public void testAddData() throws Exception { 127 File dir = getEmptyDir("testAddData"); 128 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 129 Looper.getMainLooper()); 130 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 131 132 long before = System.currentTimeMillis(); 133 Thread.sleep(1); 134 dropbox.addData("DropBoxTest", "TEST".getBytes(), 0); 135 Thread.sleep(1); 136 long after = System.currentTimeMillis(); 137 138 DropBoxManager.Entry e = dropbox.getNextEntry("DropBoxTest", before); 139 assertNotNull(e); 140 assertNull(dropbox.getNextEntry("DropBoxTest", e.getTimeMillis())); 141 142 assertEquals("DropBoxTest", e.getTag()); 143 assertTrue(e.getTimeMillis() >= before); 144 assertEquals(0, e.getFlags()); 145 assertTrue(null == e.getText(80)); 146 147 byte[] buf = new byte[80]; 148 assertEquals("TEST", new String(buf, 0, e.getInputStream().read(buf))); 149 150 e.close(); 151 } 152 153 public void testAddFile() throws Exception { 154 File dir = getEmptyDir("testAddFile"); 155 long before = System.currentTimeMillis(); 156 157 File clientDir = getEmptyDir("testAddFile_client"); 158 159 File f0 = new File(clientDir, "f0.txt"); 160 File f1 = new File(clientDir, "f1.txt.gz"); 161 File f2 = new File(clientDir, "f2.dat"); 162 File f3 = new File(clientDir, "f2.dat.gz"); 163 164 FileWriter w0 = new FileWriter(f0); 165 GZIPOutputStream gz1 = new GZIPOutputStream(new FileOutputStream(f1)); 166 FileOutputStream os2 = new FileOutputStream(f2); 167 GZIPOutputStream gz3 = new GZIPOutputStream(new FileOutputStream(f3)); 168 169 w0.write("FILE0"); 170 gz1.write("FILE1".getBytes()); 171 os2.write("DATA2".getBytes()); 172 gz3.write("DATA3".getBytes()); 173 174 w0.close(); 175 gz1.close(); 176 os2.close(); 177 gz3.close(); 178 179 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 180 Looper.getMainLooper()); 181 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 182 183 dropbox.addFile("DropBoxTest", f0, DropBoxManager.IS_TEXT); 184 dropbox.addFile("DropBoxTest", f1, DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED); 185 dropbox.addFile("DropBoxTest", f2, 0); 186 dropbox.addFile("DropBoxTest", f3, DropBoxManager.IS_GZIPPED); 187 188 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 189 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 190 DropBoxManager.Entry e2 = dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis()); 191 DropBoxManager.Entry e3 = dropbox.getNextEntry("DropBoxTest", e2.getTimeMillis()); 192 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e3.getTimeMillis())); 193 194 assertTrue(e0.getTimeMillis() > before); 195 assertTrue(e1.getTimeMillis() > e0.getTimeMillis()); 196 assertTrue(e2.getTimeMillis() > e1.getTimeMillis()); 197 assertTrue(e3.getTimeMillis() > e2.getTimeMillis()); 198 199 assertEquals(DropBoxManager.IS_TEXT, e0.getFlags()); 200 assertEquals(DropBoxManager.IS_TEXT, e1.getFlags()); 201 assertEquals(0, e2.getFlags()); 202 assertEquals(0, e3.getFlags()); 203 204 assertEquals("FILE0", e0.getText(80)); 205 206 byte[] buf1 = new byte[80]; 207 assertEquals("FILE1", new String(buf1, 0, e1.getInputStream().read(buf1))); 208 209 assertTrue(null == e2.getText(80)); 210 byte[] buf2 = new byte[80]; 211 assertEquals("DATA2", new String(buf2, 0, e2.getInputStream().read(buf2))); 212 213 assertTrue(null == e3.getText(80)); 214 byte[] buf3 = new byte[80]; 215 assertEquals("DATA3", new String(buf3, 0, e3.getInputStream().read(buf3))); 216 217 e0.close(); 218 e1.close(); 219 e2.close(); 220 e3.close(); 221 } 222 testAddEntry_Success()223 public void testAddEntry_Success() throws Exception { 224 File dir = getEmptyDir("testAddEntry"); 225 long before = System.currentTimeMillis(); 226 227 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 228 Looper.getMainLooper()); 229 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 230 231 LocalServices.getService(DropBoxManagerInternal.class).addEntry("DropBoxTest", 232 new EntrySource() { 233 @Override 234 public void writeTo(FileDescriptor fd) throws IOException { 235 try (FileOutputStream out = new FileOutputStream(fd)) { 236 out.write("test".getBytes(StandardCharsets.UTF_8)); 237 } 238 } 239 240 @Override 241 public void close() throws IOException { 242 } 243 244 @Override 245 public long length() { 246 return 0; 247 } 248 }, DropBoxManager.IS_TEXT); 249 250 DropBoxManager.Entry entry = dropbox.getNextEntry("DropBoxTest", before); 251 assertEquals(DropBoxManager.IS_TEXT, entry.getFlags()); 252 assertEquals("test", new String(Streams.readFully(entry.getInputStream()))); 253 } 254 testAddEntry_Failure()255 public void testAddEntry_Failure() throws Exception { 256 File dir = getEmptyDir("testAddEntry"); 257 long before = System.currentTimeMillis(); 258 259 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 260 Looper.getMainLooper()); 261 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 262 263 LocalServices.getService(DropBoxManagerInternal.class).addEntry("DropBoxTest", 264 new EntrySource() { 265 @Override 266 public void writeTo(FileDescriptor fd) throws IOException { 267 throw new IOException(); 268 } 269 270 @Override 271 public void close() throws IOException { 272 } 273 274 @Override 275 public long length() { 276 return 0; 277 } 278 }, DropBoxManager.IS_TEXT); 279 280 DropBoxManager.Entry entry = dropbox.getNextEntry("DropBoxTest", before); 281 assertNull(entry); 282 } 283 testAddEntriesInTheFuture()284 public void testAddEntriesInTheFuture() throws Exception { 285 File dir = getEmptyDir("testAddEntriesInTheFuture"); 286 long before = System.currentTimeMillis(); 287 288 // Near future: should be allowed to persist 289 FileWriter w0 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 5000) + ".txt")); 290 w0.write("FUTURE0"); 291 w0.close(); 292 293 // Far future: should be collapsed 294 FileWriter w1 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 100000) + ".txt")); 295 w1.write("FUTURE1"); 296 w1.close(); 297 298 // Another far future item, this one gzipped 299 File f2 = new File(dir, "DropBoxTest@" + (before + 100001) + ".txt.gz"); 300 GZIPOutputStream gz2 = new GZIPOutputStream(new FileOutputStream(f2)); 301 gz2.write("FUTURE2".getBytes()); 302 gz2.close(); 303 304 // Tombstone in the far future 305 new FileOutputStream(new File(dir, "DropBoxTest@" + (before + 100002) + ".lost")).close(); 306 307 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 308 Looper.getMainLooper()); 309 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 310 311 // Until a write, the timestamps are taken at face value 312 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 313 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 314 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 315 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 316 assertTrue(null == dropbox.getNextEntry(null, e3.getTimeMillis())); 317 318 assertEquals("FUTURE0", e0.getText(80)); 319 assertEquals("FUTURE1", e1.getText(80)); 320 assertEquals("FUTURE2", e2.getText(80)); 321 assertEquals(null, e3.getText(80)); 322 323 assertEquals(before + 5000, e0.getTimeMillis()); 324 assertEquals(before + 100000, e1.getTimeMillis()); 325 assertEquals(before + 100001, e2.getTimeMillis()); 326 assertEquals(before + 100002, e3.getTimeMillis()); 327 328 e0.close(); 329 e1.close(); 330 e2.close(); 331 e3.close(); 332 333 // Write something to force a collapse 334 dropbox.addText("NotDropBoxTest", "FUTURE"); 335 e0 = dropbox.getNextEntry(null, before); 336 e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 337 e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 338 e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 339 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e3.getTimeMillis())); 340 341 assertEquals("FUTURE0", e0.getText(80)); 342 assertEquals("FUTURE1", e1.getText(80)); 343 assertEquals("FUTURE2", e2.getText(80)); 344 assertEquals(null, e3.getText(80)); 345 346 assertEquals(before + 5000, e0.getTimeMillis()); 347 assertEquals(before + 5001, e1.getTimeMillis()); 348 assertEquals(before + 5002, e2.getTimeMillis()); 349 assertEquals(before + 5003, e3.getTimeMillis()); 350 351 e0.close(); 352 e1.close(); 353 e2.close(); 354 e3.close(); 355 } 356 testIsTagEnabled()357 public void testIsTagEnabled() throws Exception { 358 File dir = getEmptyDir("testIsTagEnabled"); 359 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 360 Looper.getMainLooper()); 361 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 362 363 long before = System.currentTimeMillis(); 364 dropbox.addText("DropBoxTest", "TEST-ENABLED"); 365 assertTrue(dropbox.isTagEnabled("DropBoxTest")); 366 367 ContentResolver cr = getContext().getContentResolver(); 368 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", 369 "disabled"); 370 371 dropbox.addText("DropBoxTest", "TEST-DISABLED"); 372 assertFalse(dropbox.isTagEnabled("DropBoxTest")); 373 374 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", 375 ""); 376 377 dropbox.addText("DropBoxTest", "TEST-ENABLED-AGAIN"); 378 assertTrue(dropbox.isTagEnabled("DropBoxTest")); 379 380 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 381 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 382 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis())); 383 384 assertEquals("TEST-ENABLED", e0.getText(80)); 385 assertEquals("TEST-ENABLED-AGAIN", e1.getText(80)); 386 387 e0.close(); 388 e1.close(); 389 } 390 testGetNextEntry()391 public void testGetNextEntry() throws Exception { 392 File dir = getEmptyDir("testGetNextEntry"); 393 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 394 Looper.getMainLooper()); 395 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 396 397 long before = System.currentTimeMillis(); 398 dropbox.addText("DropBoxTest.A", "A0"); 399 dropbox.addText("DropBoxTest.B", "B0"); 400 dropbox.addText("DropBoxTest.A", "A1"); 401 402 DropBoxManager.Entry a0 = dropbox.getNextEntry("DropBoxTest.A", before); 403 DropBoxManager.Entry a1 = dropbox.getNextEntry("DropBoxTest.A", a0.getTimeMillis()); 404 assertTrue(null == dropbox.getNextEntry("DropBoxTest.A", a1.getTimeMillis())); 405 406 DropBoxManager.Entry b0 = dropbox.getNextEntry("DropBoxTest.B", before); 407 assertTrue(null == dropbox.getNextEntry("DropBoxTest.B", b0.getTimeMillis())); 408 409 DropBoxManager.Entry x0 = dropbox.getNextEntry(null, before); 410 DropBoxManager.Entry x1 = dropbox.getNextEntry(null, x0.getTimeMillis()); 411 DropBoxManager.Entry x2 = dropbox.getNextEntry(null, x1.getTimeMillis()); 412 assertTrue(null == dropbox.getNextEntry(null, x2.getTimeMillis())); 413 414 assertEquals("DropBoxTest.A", a0.getTag()); 415 assertEquals("DropBoxTest.A", a1.getTag()); 416 assertEquals("A0", a0.getText(80)); 417 assertEquals("A1", a1.getText(80)); 418 419 assertEquals("DropBoxTest.B", b0.getTag()); 420 assertEquals("B0", b0.getText(80)); 421 422 assertEquals("DropBoxTest.A", x0.getTag()); 423 assertEquals("DropBoxTest.B", x1.getTag()); 424 assertEquals("DropBoxTest.A", x2.getTag()); 425 assertEquals("A0", x0.getText(80)); 426 assertEquals("B0", x1.getText(80)); 427 assertEquals("A1", x2.getText(80)); 428 429 a0.close(); 430 a1.close(); 431 b0.close(); 432 x0.close(); 433 x1.close(); 434 x2.close(); 435 } 436 testSizeLimits()437 public void testSizeLimits() throws Exception { 438 File dir = getEmptyDir("testSizeLimits"); 439 int blockSize = new StatFs(dir.getPath()).getBlockSize(); 440 441 // Limit storage to 10 blocks 442 int kb = blockSize * 10 / 1024; 443 ContentResolver cr = getContext().getContentResolver(); 444 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, Integer.toString(kb)); 445 446 // Three tags using a total of 12 blocks: 447 // DropBoxTest0 [ ][ ] 448 // DropBoxTest1 [x][ ][ ][ ][xxx(20 blocks)xxx] 449 // DropBoxTest2 [xxxxxxxxxx][ ][ ] 450 // 451 // The blocks marked "x" will be removed due to storage restrictions. 452 // Use random fill (so it doesn't compress), subtract a little for gzip overhead 453 454 final int overhead = 64; 455 long before = System.currentTimeMillis(); 456 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 457 Looper.getMainLooper()); 458 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 459 460 addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); 461 addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); 462 463 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 464 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 465 addRandomEntry(dropbox, "DropBoxTest1", blockSize * 2 - overhead); 466 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 467 addRandomEntry(dropbox, "DropBoxTest1", blockSize * 20 - overhead); 468 469 addRandomEntry(dropbox, "DropBoxTest2", blockSize * 4 - overhead); 470 addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead); 471 addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead); 472 473 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 474 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 475 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 476 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 477 DropBoxManager.Entry e4 = dropbox.getNextEntry(null, e3.getTimeMillis()); 478 DropBoxManager.Entry e5 = dropbox.getNextEntry(null, e4.getTimeMillis()); 479 DropBoxManager.Entry e6 = dropbox.getNextEntry(null, e5.getTimeMillis()); 480 DropBoxManager.Entry e7 = dropbox.getNextEntry(null, e6.getTimeMillis()); 481 DropBoxManager.Entry e8 = dropbox.getNextEntry(null, e7.getTimeMillis()); 482 DropBoxManager.Entry e9 = dropbox.getNextEntry(null, e8.getTimeMillis()); 483 assertTrue(null == dropbox.getNextEntry(null, e9.getTimeMillis())); 484 485 assertEquals("DropBoxTest0", e0.getTag()); 486 assertEquals("DropBoxTest0", e1.getTag()); 487 assertEquals(blockSize - overhead, getEntrySize(e0)); 488 assertEquals(blockSize - overhead, getEntrySize(e1)); 489 490 assertEquals("DropBoxTest1", e2.getTag()); 491 assertEquals("DropBoxTest1", e3.getTag()); 492 assertEquals("DropBoxTest1", e4.getTag()); 493 assertEquals("DropBoxTest1", e5.getTag()); 494 assertEquals("DropBoxTest1", e6.getTag()); 495 assertEquals(-1, getEntrySize(e2)); // Tombstone 496 assertEquals(blockSize - overhead, getEntrySize(e3)); 497 assertEquals(blockSize * 2 - overhead, getEntrySize(e4)); 498 assertEquals(blockSize - overhead, getEntrySize(e5)); 499 assertEquals(-1, getEntrySize(e6)); 500 501 assertEquals("DropBoxTest2", e7.getTag()); 502 assertEquals("DropBoxTest2", e8.getTag()); 503 assertEquals("DropBoxTest2", e9.getTag()); 504 assertEquals(-1, getEntrySize(e7)); // Tombstone 505 assertEquals(blockSize - overhead, getEntrySize(e8)); 506 assertEquals(blockSize - overhead, getEntrySize(e9)); 507 508 e0.close(); 509 e1.close(); 510 e2.close(); 511 e3.close(); 512 e4.close(); 513 e5.close(); 514 e6.close(); 515 e7.close(); 516 e8.close(); 517 e9.close(); 518 519 // Specifying a tag name skips tombstone records. 520 521 DropBoxManager.Entry t0 = dropbox.getNextEntry("DropBoxTest1", before); 522 DropBoxManager.Entry t1 = dropbox.getNextEntry("DropBoxTest1", t0.getTimeMillis()); 523 DropBoxManager.Entry t2 = dropbox.getNextEntry("DropBoxTest1", t1.getTimeMillis()); 524 assertTrue(null == dropbox.getNextEntry("DropBoxTest1", t2.getTimeMillis())); 525 526 assertEquals("DropBoxTest1", t0.getTag()); 527 assertEquals("DropBoxTest1", t1.getTag()); 528 assertEquals("DropBoxTest1", t2.getTag()); 529 530 assertEquals(blockSize - overhead, getEntrySize(t0)); 531 assertEquals(blockSize * 2 - overhead, getEntrySize(t1)); 532 assertEquals(blockSize - overhead, getEntrySize(t2)); 533 534 t0.close(); 535 t1.close(); 536 t2.close(); 537 } 538 testAgeLimits()539 public void testAgeLimits() throws Exception { 540 File dir = getEmptyDir("testAgeLimits"); 541 int blockSize = new StatFs(dir.getPath()).getBlockSize(); 542 543 // Limit storage to 10 blocks with an expiration of 1 second 544 int kb = blockSize * 10 / 1024; 545 ContentResolver cr = getContext().getContentResolver(); 546 Settings.Global.putString(cr, Settings.Global.DROPBOX_AGE_SECONDS, "1"); 547 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, Integer.toString(kb)); 548 549 // Write one normal entry and another so big that it is instantly tombstoned 550 long before = System.currentTimeMillis(); 551 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 552 Looper.getMainLooper()); 553 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 554 555 dropbox.addText("DropBoxTest", "TEST"); 556 addRandomEntry(dropbox, "DropBoxTest", blockSize * 20); 557 558 // Verify that things are as expected 559 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 560 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 561 assertTrue(null == dropbox.getNextEntry(null, e1.getTimeMillis())); 562 563 assertEquals("TEST", e0.getText(80)); 564 assertEquals(null, e1.getText(80)); 565 assertEquals(-1, getEntrySize(e1)); 566 567 e0.close(); 568 e1.close(); 569 570 // Wait a second and write another entry -- old ones should be expunged 571 Thread.sleep(2000); 572 dropbox.addText("DropBoxTest", "TEST1"); 573 574 e0 = dropbox.getNextEntry(null, before); 575 assertTrue(null == dropbox.getNextEntry(null, e0.getTimeMillis())); 576 assertEquals("TEST1", e0.getText(80)); 577 e0.close(); 578 } 579 testFileCountLimits()580 public void testFileCountLimits() throws Exception { 581 File dir = getEmptyDir("testFileCountLimits"); 582 583 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 584 Looper.getMainLooper()); 585 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 586 dropbox.addText("DropBoxTest", "TEST0"); 587 dropbox.addText("DropBoxTest", "TEST1"); 588 dropbox.addText("DropBoxTest", "TEST2"); 589 dropbox.addText("DropBoxTest", "TEST3"); 590 dropbox.addText("DropBoxTest", "TEST4"); 591 dropbox.addText("DropBoxTest", "TEST5"); 592 593 // Verify 6 files added 594 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, 0); 595 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 596 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 597 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 598 DropBoxManager.Entry e4 = dropbox.getNextEntry(null, e3.getTimeMillis()); 599 DropBoxManager.Entry e5 = dropbox.getNextEntry(null, e4.getTimeMillis()); 600 assertTrue(null == dropbox.getNextEntry(null, e5.getTimeMillis())); 601 assertEquals("TEST0", e0.getText(80)); 602 assertEquals("TEST5", e5.getText(80)); 603 604 e0.close(); 605 e1.close(); 606 e2.close(); 607 e3.close(); 608 e4.close(); 609 e5.close(); 610 611 // Limit to 3 files and add one more entry 612 ContentResolver cr = getContext().getContentResolver(); 613 Settings.Global.putString(cr, Settings.Global.DROPBOX_MAX_FILES, "3"); 614 dropbox.addText("DropBoxTest", "TEST6"); 615 616 // Verify only 3 files left 617 DropBoxManager.Entry f0 = dropbox.getNextEntry(null, 0); 618 DropBoxManager.Entry f1 = dropbox.getNextEntry(null, f0.getTimeMillis()); 619 DropBoxManager.Entry f2 = dropbox.getNextEntry(null, f1.getTimeMillis()); 620 assertTrue(null == dropbox.getNextEntry(null, f2.getTimeMillis())); 621 assertEquals("TEST4", f0.getText(80)); 622 assertEquals("TEST5", f1.getText(80)); 623 assertEquals("TEST6", f2.getText(80)); 624 625 f0.close(); 626 f1.close(); 627 f2.close(); 628 } 629 testCreateDropBoxManagerWithInvalidDirectory()630 public void testCreateDropBoxManagerWithInvalidDirectory() throws Exception { 631 // If created with an invalid directory, the DropBoxManager should suffer quietly 632 // and fail all operations (this is how it survives a full disk). 633 // Once the directory becomes possible to create, it will start working. 634 635 File dir = new File(getEmptyDir("testCreateDropBoxManagerWith"), "InvalidDirectory"); 636 new FileOutputStream(dir).close(); // Create an empty file 637 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir, 638 Looper.getMainLooper()); 639 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 640 641 dropbox.addText("DropBoxTest", "should be ignored"); 642 dropbox.addData("DropBoxTest", "should be ignored".getBytes(), 0); 643 assertTrue(null == dropbox.getNextEntry("DropBoxTest", 0)); 644 645 dir.delete(); // Remove the file so a directory can be created 646 dropbox.addText("DropBoxTest", "TEST"); 647 DropBoxManager.Entry e = dropbox.getNextEntry("DropBoxTest", 0); 648 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e.getTimeMillis())); 649 assertEquals("DropBoxTest", e.getTag()); 650 assertEquals("TEST", e.getText(80)); 651 e.close(); 652 } 653 testDropBoxEntrySerialization()654 public void testDropBoxEntrySerialization() throws Exception { 655 // Make sure DropBoxManager.Entry can be serialized to a Parcel and back 656 // under a variety of conditions. 657 658 Parcel parcel = Parcel.obtain(); 659 File dir = getEmptyDir("testDropBoxEntrySerialization"); 660 661 new DropBoxManager.Entry("empty", 1000000).writeToParcel(parcel, 0); 662 new DropBoxManager.Entry("string", 2000000, "String Value").writeToParcel(parcel, 0); 663 new DropBoxManager.Entry("bytes", 3000000, "Bytes Value".getBytes(), 664 DropBoxManager.IS_TEXT).writeToParcel(parcel, 0); 665 new DropBoxManager.Entry("zerobytes", 4000000, new byte[0], 0).writeToParcel(parcel, 0); 666 new DropBoxManager.Entry("emptybytes", 5000000, (byte[]) null, 667 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 668 669 try { 670 new DropBoxManager.Entry("badbytes", 99999, 671 "Bad Bytes Value".getBytes(), 672 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 673 fail("IllegalArgumentException expected for non-null byte[] and IS_EMPTY flags"); 674 } catch (IllegalArgumentException e) { 675 // expected 676 } 677 678 try { 679 new DropBoxManager.Entry("badbytes", 99999, (byte[]) null, 0).writeToParcel(parcel, 0); 680 fail("IllegalArgumentException expected for null byte[] and non-IS_EMPTY flags"); 681 } catch (IllegalArgumentException e) { 682 // expected 683 } 684 685 File f = new File(dir, "file.dat"); 686 FileOutputStream os = new FileOutputStream(f); 687 os.write("File Value".getBytes()); 688 os.close(); 689 690 new DropBoxManager.Entry("file", 6000000, f, DropBoxManager.IS_TEXT).writeToParcel( 691 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 692 new DropBoxManager.Entry("binfile", 7000000, f, 0).writeToParcel( 693 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 694 new DropBoxManager.Entry("emptyfile", 8000000, (ParcelFileDescriptor) null, 695 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 696 697 try { 698 new DropBoxManager.Entry("badfile", 99999, new File(dir, "nonexist.dat"), 0); 699 fail("IOException expected for nonexistent file"); 700 } catch (IOException e) { 701 // expected 702 } 703 704 try { 705 new DropBoxManager.Entry("badfile", 99999, f, DropBoxManager.IS_EMPTY).writeToParcel( 706 parcel, 0); 707 fail("IllegalArgumentException expected for non-null file and IS_EMPTY flags"); 708 } catch (IllegalArgumentException e) { 709 // expected 710 } 711 712 try { 713 new DropBoxManager.Entry("badfile", 99999, (ParcelFileDescriptor) null, 0); 714 fail("IllegalArgumentException expected for null PFD and non-IS_EMPTY flags"); 715 } catch (IllegalArgumentException e) { 716 // expected 717 } 718 719 File gz = new File(dir, "file.gz"); 720 GZIPOutputStream gzout = new GZIPOutputStream(new FileOutputStream(gz)); 721 gzout.write("Gzip File Value".getBytes()); 722 gzout.close(); 723 724 new DropBoxManager.Entry("gzipfile", 9000000, gz, 725 DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED).writeToParcel( 726 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 727 new DropBoxManager.Entry("gzipbinfile", 10000000, gz, 728 DropBoxManager.IS_GZIPPED).writeToParcel( 729 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 730 731 // 732 // Switch from writing to reading 733 // 734 735 parcel.setDataPosition(0); 736 DropBoxManager.Entry e; 737 738 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 739 assertEquals("empty", e.getTag()); 740 assertEquals(1000000, e.getTimeMillis()); 741 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 742 assertEquals(null, e.getText(100)); 743 assertEquals(null, e.getInputStream()); 744 e.close(); 745 746 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 747 assertEquals("string", e.getTag()); 748 assertEquals(2000000, e.getTimeMillis()); 749 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 750 assertEquals("String Value", e.getText(100)); 751 assertEquals("String Value", 752 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 753 e.close(); 754 755 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 756 assertEquals("bytes", e.getTag()); 757 assertEquals(3000000, e.getTimeMillis()); 758 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 759 assertEquals("Bytes Value", e.getText(100)); 760 e.close(); 761 762 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 763 assertEquals("zerobytes", e.getTag()); 764 assertEquals(4000000, e.getTimeMillis()); 765 assertEquals(0, e.getFlags()); 766 assertEquals(null, e.getText(100)); 767 assertEquals(null, 768 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 769 e.close(); 770 771 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 772 assertEquals("emptybytes", e.getTag()); 773 assertEquals(5000000, e.getTimeMillis()); 774 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 775 assertEquals(null, e.getText(100)); 776 assertEquals(null, e.getInputStream()); 777 e.close(); 778 779 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 780 assertEquals("file", e.getTag()); 781 assertEquals(6000000, e.getTimeMillis()); 782 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 783 assertEquals("File Value", e.getText(100)); 784 e.close(); 785 786 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 787 assertEquals("binfile", e.getTag()); 788 assertEquals(7000000, e.getTimeMillis()); 789 assertEquals(0, e.getFlags()); 790 assertEquals(null, e.getText(100)); 791 assertEquals("File Value", 792 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 793 e.close(); 794 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 795 assertEquals("emptyfile", e.getTag()); 796 assertEquals(8000000, e.getTimeMillis()); 797 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 798 assertEquals(null, e.getText(100)); 799 assertEquals(null, e.getInputStream()); 800 e.close(); 801 802 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 803 assertEquals("gzipfile", e.getTag()); 804 assertEquals(9000000, e.getTimeMillis()); 805 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 806 assertEquals("Gzip File Value", e.getText(100)); 807 e.close(); 808 809 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 810 assertEquals("gzipbinfile", e.getTag()); 811 assertEquals(10000000, e.getTimeMillis()); 812 assertEquals(0, e.getFlags()); 813 assertEquals(null, e.getText(100)); 814 assertEquals("Gzip File Value", 815 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 816 e.close(); 817 assertEquals(0, parcel.dataAvail()); 818 parcel.recycle(); 819 } 820 testDropBoxEntrySerializationDoesntLeakFileDescriptors()821 public void testDropBoxEntrySerializationDoesntLeakFileDescriptors() throws Exception { 822 File dir = getEmptyDir("testDropBoxEntrySerialization"); 823 File f = new File(dir, "file.dat"); 824 FileOutputStream os = new FileOutputStream(f); 825 os.write("File Value".getBytes()); 826 os.close(); 827 828 int before = countOpenFiles(); 829 assertTrue(before > 0); 830 831 for (int i = 0; i < 1000; i++) { 832 Parcel parcel = Parcel.obtain(); 833 new DropBoxManager.Entry("file", 1000000, f, 0).writeToParcel( 834 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 835 836 parcel.setDataPosition(0); 837 DropBoxManager.Entry e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 838 assertEquals("file", e.getTag()); 839 e.close(); 840 841 parcel.recycle(); 842 } 843 844 int after = countOpenFiles(); 845 assertTrue(after > 0); 846 assertTrue(after < before + 20); 847 } 848 849 public void testEntryFile() throws Exception { 850 File fromDir = getEmptyDir("testEntryFile_from"); 851 File toDir = getEmptyDir("testEntryFile_to"); 852 853 { 854 File f = new File(fromDir, "f0.txt"); 855 try (FileWriter w = new FileWriter(f)) { 856 w.write("abc"); 857 } 858 859 EntryFile e = new EntryFile(f, toDir, "tag:!", 12345, DropBoxManager.IS_TEXT, 1024); 860 861 assertEquals("tag:!", e.tag); 862 assertEquals(12345, e.timestampMillis); 863 assertEquals(DropBoxManager.IS_TEXT, e.flags); 864 assertEquals(1, e.blocks); 865 866 assertFalse(f.exists()); // Because it should be renamed. 867 868 assertTrue(e.hasFile()); 869 assertEquals(new File(toDir, "tag%3A!@12345.txt"), e.getFile(toDir)); 870 assertTrue(e.getFile(toDir).exists()); 871 } 872 // Same test with gzip. 873 { 874 File f = new File(fromDir, "f0.txt.gz"); // It's a lie; it's not actually gz. 875 try (FileWriter w = new FileWriter(f)) { 876 w.write("abc"); 877 } 878 879 EntryFile e = new EntryFile(f, toDir, "tag:!", 12345, 880 DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED, 1024); 881 882 assertEquals("tag:!", e.tag); 883 884 assertFalse(f.exists()); // Because it should be renamed. 885 886 assertTrue(e.hasFile()); 887 assertEquals(new File(toDir, "tag%3A!@12345.txt.gz"), e.getFile(toDir)); 888 assertTrue(e.getFile(toDir).exists()); 889 890 } 891 // binary, gzip. 892 { 893 File f = new File(fromDir, "f0.dat.gz"); // It's a lie; it's not actually gz. 894 try (FileWriter w = new FileWriter(f)) { 895 w.write("abc"); 896 } 897 898 EntryFile e = new EntryFile(f, toDir, "tag:!", 12345, 899 DropBoxManager.IS_GZIPPED, 1024); 900 901 assertEquals("tag:!", e.tag); 902 903 assertFalse(f.exists()); // Because it should be renamed. 904 905 assertTrue(e.hasFile()); 906 assertEquals(new File(toDir, "tag%3A!@12345.dat.gz"), e.getFile(toDir)); 907 assertTrue(e.getFile(toDir).exists()); 908 909 } 910 911 // Tombstone. 912 { 913 EntryFile e = new EntryFile(toDir, "tag:!", 12345); 914 915 assertEquals("tag:!", e.tag); 916 assertEquals(12345, e.timestampMillis); 917 assertEquals(DropBoxManager.IS_EMPTY, e.flags); 918 assertEquals(0, e.blocks); 919 920 assertTrue(e.hasFile()); 921 assertEquals(new File(toDir, "tag%3A!@12345.lost"), e.getFile(toDir)); 922 assertTrue(e.getFile(toDir).exists()); 923 } 924 925 // From existing files. 926 { 927 File f = new File(fromDir, "tag%3A!@12345.dat"); 928 f.createNewFile(); 929 930 EntryFile e = new EntryFile(f, 1024); 931 932 assertEquals("tag:!", e.tag); 933 assertEquals(12345, e.timestampMillis); 934 assertEquals(0, e.flags); 935 assertEquals(0, e.blocks); 936 937 assertTrue(f.exists()); 938 } 939 { 940 File f = new File(fromDir, "tag%3A!@12345.dat.gz"); 941 f.createNewFile(); 942 943 EntryFile e = new EntryFile(f, 1024); 944 945 assertEquals("tag:!", e.tag); 946 assertEquals(12345, e.timestampMillis); 947 assertEquals(DropBoxManager.IS_GZIPPED, e.flags); 948 assertEquals(0, e.blocks); 949 950 assertTrue(f.exists()); 951 } 952 { 953 File f = new File(fromDir, "tag%3A!@12345.txt"); 954 try (FileWriter w = new FileWriter(f)) { 955 w.write(new char[1024]); 956 } 957 958 EntryFile e = new EntryFile(f, 1024); 959 960 assertEquals("tag:!", e.tag); 961 assertEquals(12345, e.timestampMillis); 962 assertEquals(DropBoxManager.IS_TEXT, e.flags); 963 assertEquals(1, e.blocks); 964 965 assertTrue(f.exists()); 966 } 967 { 968 File f = new File(fromDir, "tag%3A!@12345.txt.gz"); 969 try (FileWriter w = new FileWriter(f)) { 970 w.write(new char[1025]); 971 } 972 973 EntryFile e = new EntryFile(f, 1024); 974 975 assertEquals("tag:!", e.tag); 976 assertEquals(12345, e.timestampMillis); 977 assertEquals(DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED, e.flags); 978 assertEquals(2, e.blocks); 979 980 assertTrue(f.exists()); 981 } 982 { 983 File f = new File(fromDir, "tag%3A!@12345.lost"); 984 f.createNewFile(); 985 986 EntryFile e = new EntryFile(f, 1024); 987 988 assertEquals("tag:!", e.tag); 989 assertEquals(12345, e.timestampMillis); 990 assertEquals(DropBoxManager.IS_EMPTY, e.flags); 991 assertEquals(0, e.blocks); 992 993 assertTrue(f.exists()); 994 } 995 { 996 File f = new File(fromDir, "@12345.dat"); // Empty tag -- this actually works. 997 f.createNewFile(); 998 999 EntryFile e = new EntryFile(f, 1024); 1000 1001 assertEquals("", e.tag); 1002 assertEquals(12345, e.timestampMillis); 1003 assertEquals(0, e.flags); 1004 assertEquals(0, e.blocks); 1005 1006 assertTrue(f.exists()); 1007 } 1008 // From invalid filenames. 1009 { 1010 File f = new File(fromDir, "tag.dat"); // No @. 1011 f.createNewFile(); 1012 1013 EntryFile e = new EntryFile(f, 1024); 1014 1015 assertEquals(null, e.tag); 1016 assertEquals(0, e.timestampMillis); 1017 assertEquals(DropBoxManager.IS_EMPTY, e.flags); 1018 assertEquals(0, e.blocks); 1019 1020 assertFalse(f.exists()); 1021 } 1022 { 1023 File f = new File(fromDir, "tag@.dat"); // Invalid timestamp. 1024 f.createNewFile(); 1025 1026 EntryFile e = new EntryFile(f, 1024); 1027 1028 assertEquals(null, e.tag); 1029 assertEquals(0, e.timestampMillis); 1030 assertEquals(DropBoxManager.IS_EMPTY, e.flags); 1031 assertEquals(0, e.blocks); 1032 1033 assertFalse(f.exists()); 1034 } 1035 { 1036 File f = new File(fromDir, "tag@12345.daxt"); // Invalid extension. 1037 f.createNewFile(); 1038 1039 EntryFile e = new EntryFile(f, 1024); 1040 1041 assertEquals(null, e.tag); 1042 assertEquals(0, e.timestampMillis); 1043 assertEquals(DropBoxManager.IS_EMPTY, e.flags); 1044 assertEquals(0, e.blocks); 1045 1046 assertFalse(f.exists()); 1047 } 1048 } 1049 1050 public void testCompareEntries() { 1051 File dir = getEmptyDir("testCompareEntries"); 1052 assertEquals(-1, 1053 new EntryFile(new File(dir, "aaa@100.dat"), 1).compareTo( 1054 new EntryFile(new File(dir, "bbb@200.dat"), 1))); 1055 assertEquals(1, 1056 new EntryFile(new File(dir, "aaa@200.dat"), 1).compareTo( 1057 new EntryFile(new File(dir, "bbb@100.dat"), 1))); 1058 assertEquals(-1, 1059 new EntryFile(new File(dir, "aaa@100.dat"), 1).compareTo( 1060 new EntryFile(new File(dir, "bbb@100.dat"), 1))); 1061 assertEquals(1, 1062 new EntryFile(new File(dir, "bbb@100.dat"), 1).compareTo( 1063 new EntryFile(new File(dir, "aaa@100.dat"), 1))); 1064 } 1065 1066 private void addRandomEntry(DropBoxManager dropbox, String tag, int size) throws Exception { 1067 byte[] bytes = new byte[size]; 1068 new Random(System.currentTimeMillis()).nextBytes(bytes); 1069 1070 File f = new File(getEmptyDir("addRandomEntry"), "random.dat"); 1071 FileOutputStream os = new FileOutputStream(f); 1072 os.write(bytes); 1073 os.close(); 1074 1075 dropbox.addFile(tag, f, 0); 1076 } 1077 1078 private int getEntrySize(DropBoxManager.Entry e) throws Exception { 1079 InputStream is = e.getInputStream(); 1080 if (is == null) return -1; 1081 int length = 0; 1082 while (is.read() != -1) length++; 1083 return length; 1084 } 1085 1086 private void recursiveDelete(File file) { 1087 if (!file.delete() && file.isDirectory()) { 1088 for (File f : file.listFiles()) recursiveDelete(f); 1089 file.delete(); 1090 } 1091 } 1092 1093 private File getEmptyDir(String name) { 1094 File dir = getContext().getDir("DropBoxTest." + name, 0); 1095 for (File f : dir.listFiles()) recursiveDelete(f); 1096 assertTrue(dir.listFiles().length == 0); 1097 return dir; 1098 } 1099 1100 private int countOpenFiles() { 1101 return new File("/proc/" + Process.myPid() + "/fd").listFiles().length; 1102 } 1103 } 1104