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.Intent; 22 import android.os.DropBoxManager; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.os.ParcelFileDescriptor; 26 import android.os.Process; 27 import android.os.ServiceManager; 28 import android.os.StatFs; 29 import android.provider.Settings; 30 import android.test.AndroidTestCase; 31 32 import com.android.server.DropBoxManagerService; 33 34 import java.io.BufferedReader; 35 import java.io.File; 36 import java.io.FileOutputStream; 37 import java.io.FileWriter; 38 import java.io.IOException; 39 import java.io.InputStream; 40 import java.io.InputStreamReader; 41 import java.util.Random; 42 import java.util.zip.GZIPOutputStream; 43 44 /** Test {@link DropBoxManager} functionality. */ 45 public class DropBoxTest extends AndroidTestCase { tearDown()46 public void tearDown() throws Exception { 47 ContentResolver cr = getContext().getContentResolver(); 48 Settings.Global.putString(cr, Settings.Global.DROPBOX_AGE_SECONDS, ""); 49 Settings.Global.putString(cr, Settings.Global.DROPBOX_MAX_FILES, ""); 50 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, ""); 51 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", ""); 52 } 53 testAddText()54 public void testAddText() throws Exception { 55 File dir = getEmptyDir("testAddText"); 56 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 57 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 58 59 long before = System.currentTimeMillis(); 60 Thread.sleep(5); 61 dropbox.addText("DropBoxTest", "TEST0"); 62 Thread.sleep(5); 63 long between = System.currentTimeMillis(); 64 Thread.sleep(5); 65 dropbox.addText("DropBoxTest", "TEST1"); 66 dropbox.addText("DropBoxTest", "TEST2"); 67 Thread.sleep(5); 68 long after = System.currentTimeMillis(); 69 70 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 71 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 72 DropBoxManager.Entry e2 = dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis()); 73 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e2.getTimeMillis())); 74 75 assertTrue(e0.getTimeMillis() > before); 76 assertTrue(e0.getTimeMillis() < between); 77 assertTrue(e1.getTimeMillis() > between); 78 assertTrue(e1.getTimeMillis() < e2.getTimeMillis()); 79 assertTrue(e2.getTimeMillis() < after); 80 81 assertEquals("TEST0", e0.getText(80)); 82 assertEquals("TEST1", e1.getText(80)); 83 assertEquals("TES", e2.getText(3)); 84 85 e0.close(); 86 e1.close(); 87 e2.close(); 88 } 89 90 public void testAddData() throws Exception { 91 File dir = getEmptyDir("testAddData"); 92 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 93 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 94 95 long before = System.currentTimeMillis(); 96 dropbox.addData("DropBoxTest", "TEST".getBytes(), 0); 97 long after = System.currentTimeMillis(); 98 99 DropBoxManager.Entry e = dropbox.getNextEntry("DropBoxTest", before); 100 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e.getTimeMillis())); 101 102 assertEquals("DropBoxTest", e.getTag()); 103 assertTrue(e.getTimeMillis() >= before); 104 assertEquals(0, e.getFlags()); 105 assertTrue(null == e.getText(80)); 106 107 byte[] buf = new byte[80]; 108 assertEquals("TEST", new String(buf, 0, e.getInputStream().read(buf))); 109 110 e.close(); 111 } 112 113 public void testAddFile() throws Exception { 114 File dir = getEmptyDir("testAddFile"); 115 long before = System.currentTimeMillis(); 116 117 File f0 = new File(dir, "f0.txt"); 118 File f1 = new File(dir, "f1.txt.gz"); 119 File f2 = new File(dir, "f2.dat"); 120 File f3 = new File(dir, "f2.dat.gz"); 121 122 FileWriter w0 = new FileWriter(f0); 123 GZIPOutputStream gz1 = new GZIPOutputStream(new FileOutputStream(f1)); 124 FileOutputStream os2 = new FileOutputStream(f2); 125 GZIPOutputStream gz3 = new GZIPOutputStream(new FileOutputStream(f3)); 126 127 w0.write("FILE0"); 128 gz1.write("FILE1".getBytes()); 129 os2.write("DATA2".getBytes()); 130 gz3.write("DATA3".getBytes()); 131 132 w0.close(); 133 gz1.close(); 134 os2.close(); 135 gz3.close(); 136 137 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 138 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 139 140 dropbox.addFile("DropBoxTest", f0, DropBoxManager.IS_TEXT); 141 dropbox.addFile("DropBoxTest", f1, DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED); 142 dropbox.addFile("DropBoxTest", f2, 0); 143 dropbox.addFile("DropBoxTest", f3, DropBoxManager.IS_GZIPPED); 144 145 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 146 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 147 DropBoxManager.Entry e2 = dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis()); 148 DropBoxManager.Entry e3 = dropbox.getNextEntry("DropBoxTest", e2.getTimeMillis()); 149 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e3.getTimeMillis())); 150 151 assertTrue(e0.getTimeMillis() > before); 152 assertTrue(e1.getTimeMillis() > e0.getTimeMillis()); 153 assertTrue(e2.getTimeMillis() > e1.getTimeMillis()); 154 assertTrue(e3.getTimeMillis() > e2.getTimeMillis()); 155 156 assertEquals(DropBoxManager.IS_TEXT, e0.getFlags()); 157 assertEquals(DropBoxManager.IS_TEXT, e1.getFlags()); 158 assertEquals(0, e2.getFlags()); 159 assertEquals(0, e3.getFlags()); 160 161 assertEquals("FILE0", e0.getText(80)); 162 163 byte[] buf1 = new byte[80]; 164 assertEquals("FILE1", new String(buf1, 0, e1.getInputStream().read(buf1))); 165 166 assertTrue(null == e2.getText(80)); 167 byte[] buf2 = new byte[80]; 168 assertEquals("DATA2", new String(buf2, 0, e2.getInputStream().read(buf2))); 169 170 assertTrue(null == e3.getText(80)); 171 byte[] buf3 = new byte[80]; 172 assertEquals("DATA3", new String(buf3, 0, e3.getInputStream().read(buf3))); 173 174 e0.close(); 175 e1.close(); 176 e2.close(); 177 e3.close(); 178 } 179 testAddEntriesInTheFuture()180 public void testAddEntriesInTheFuture() throws Exception { 181 File dir = getEmptyDir("testAddEntriesInTheFuture"); 182 long before = System.currentTimeMillis(); 183 184 // Near future: should be allowed to persist 185 FileWriter w0 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 5000) + ".txt")); 186 w0.write("FUTURE0"); 187 w0.close(); 188 189 // Far future: should be collapsed 190 FileWriter w1 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 100000) + ".txt")); 191 w1.write("FUTURE1"); 192 w1.close(); 193 194 // Another far future item, this one gzipped 195 File f2 = new File(dir, "DropBoxTest@" + (before + 100001) + ".txt.gz"); 196 GZIPOutputStream gz2 = new GZIPOutputStream(new FileOutputStream(f2)); 197 gz2.write("FUTURE2".getBytes()); 198 gz2.close(); 199 200 // Tombstone in the far future 201 new FileOutputStream(new File(dir, "DropBoxTest@" + (before + 100002) + ".lost")).close(); 202 203 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 204 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 205 206 // Until a write, the timestamps are taken at face value 207 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 208 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 209 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 210 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 211 assertTrue(null == dropbox.getNextEntry(null, e3.getTimeMillis())); 212 213 assertEquals("FUTURE0", e0.getText(80)); 214 assertEquals("FUTURE1", e1.getText(80)); 215 assertEquals("FUTURE2", e2.getText(80)); 216 assertEquals(null, e3.getText(80)); 217 218 assertEquals(before + 5000, e0.getTimeMillis()); 219 assertEquals(before + 100000, e1.getTimeMillis()); 220 assertEquals(before + 100001, e2.getTimeMillis()); 221 assertEquals(before + 100002, e3.getTimeMillis()); 222 223 e0.close(); 224 e1.close(); 225 e2.close(); 226 e3.close(); 227 228 // Write something to force a collapse 229 dropbox.addText("NotDropBoxTest", "FUTURE"); 230 e0 = dropbox.getNextEntry(null, before); 231 e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 232 e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 233 e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 234 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e3.getTimeMillis())); 235 236 assertEquals("FUTURE0", e0.getText(80)); 237 assertEquals("FUTURE1", e1.getText(80)); 238 assertEquals("FUTURE2", e2.getText(80)); 239 assertEquals(null, e3.getText(80)); 240 241 assertEquals(before + 5000, e0.getTimeMillis()); 242 assertEquals(before + 5001, e1.getTimeMillis()); 243 assertEquals(before + 5002, e2.getTimeMillis()); 244 assertEquals(before + 5003, e3.getTimeMillis()); 245 246 e0.close(); 247 e1.close(); 248 e2.close(); 249 e3.close(); 250 } 251 testIsTagEnabled()252 public void testIsTagEnabled() throws Exception { 253 File dir = getEmptyDir("testIsTagEnabled"); 254 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 255 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 256 257 long before = System.currentTimeMillis(); 258 dropbox.addText("DropBoxTest", "TEST-ENABLED"); 259 assertTrue(dropbox.isTagEnabled("DropBoxTest")); 260 261 ContentResolver cr = getContext().getContentResolver(); 262 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", 263 "disabled"); 264 265 dropbox.addText("DropBoxTest", "TEST-DISABLED"); 266 assertFalse(dropbox.isTagEnabled("DropBoxTest")); 267 268 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", 269 ""); 270 271 dropbox.addText("DropBoxTest", "TEST-ENABLED-AGAIN"); 272 assertTrue(dropbox.isTagEnabled("DropBoxTest")); 273 274 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 275 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 276 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis())); 277 278 assertEquals("TEST-ENABLED", e0.getText(80)); 279 assertEquals("TEST-ENABLED-AGAIN", e1.getText(80)); 280 281 e0.close(); 282 e1.close(); 283 } 284 testGetNextEntry()285 public void testGetNextEntry() throws Exception { 286 File dir = getEmptyDir("testGetNextEntry"); 287 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 288 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 289 290 long before = System.currentTimeMillis(); 291 dropbox.addText("DropBoxTest.A", "A0"); 292 dropbox.addText("DropBoxTest.B", "B0"); 293 dropbox.addText("DropBoxTest.A", "A1"); 294 295 DropBoxManager.Entry a0 = dropbox.getNextEntry("DropBoxTest.A", before); 296 DropBoxManager.Entry a1 = dropbox.getNextEntry("DropBoxTest.A", a0.getTimeMillis()); 297 assertTrue(null == dropbox.getNextEntry("DropBoxTest.A", a1.getTimeMillis())); 298 299 DropBoxManager.Entry b0 = dropbox.getNextEntry("DropBoxTest.B", before); 300 assertTrue(null == dropbox.getNextEntry("DropBoxTest.B", b0.getTimeMillis())); 301 302 DropBoxManager.Entry x0 = dropbox.getNextEntry(null, before); 303 DropBoxManager.Entry x1 = dropbox.getNextEntry(null, x0.getTimeMillis()); 304 DropBoxManager.Entry x2 = dropbox.getNextEntry(null, x1.getTimeMillis()); 305 assertTrue(null == dropbox.getNextEntry(null, x2.getTimeMillis())); 306 307 assertEquals("DropBoxTest.A", a0.getTag()); 308 assertEquals("DropBoxTest.A", a1.getTag()); 309 assertEquals("A0", a0.getText(80)); 310 assertEquals("A1", a1.getText(80)); 311 312 assertEquals("DropBoxTest.B", b0.getTag()); 313 assertEquals("B0", b0.getText(80)); 314 315 assertEquals("DropBoxTest.A", x0.getTag()); 316 assertEquals("DropBoxTest.B", x1.getTag()); 317 assertEquals("DropBoxTest.A", x2.getTag()); 318 assertEquals("A0", x0.getText(80)); 319 assertEquals("B0", x1.getText(80)); 320 assertEquals("A1", x2.getText(80)); 321 322 a0.close(); 323 a1.close(); 324 b0.close(); 325 x0.close(); 326 x1.close(); 327 x2.close(); 328 } 329 testSizeLimits()330 public void testSizeLimits() throws Exception { 331 File dir = getEmptyDir("testSizeLimits"); 332 int blockSize = new StatFs(dir.getPath()).getBlockSize(); 333 334 // Limit storage to 10 blocks 335 int kb = blockSize * 10 / 1024; 336 ContentResolver cr = getContext().getContentResolver(); 337 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, Integer.toString(kb)); 338 339 // Three tags using a total of 12 blocks: 340 // DropBoxTest0 [ ][ ] 341 // DropBoxTest1 [x][ ][ ][ ][xxx(20 blocks)xxx] 342 // DropBoxTest2 [xxxxxxxxxx][ ][ ] 343 // 344 // The blocks marked "x" will be removed due to storage restrictions. 345 // Use random fill (so it doesn't compress), subtract a little for gzip overhead 346 347 final int overhead = 64; 348 long before = System.currentTimeMillis(); 349 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 350 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 351 352 addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); 353 addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); 354 355 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 356 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 357 addRandomEntry(dropbox, "DropBoxTest1", blockSize * 2 - overhead); 358 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 359 addRandomEntry(dropbox, "DropBoxTest1", blockSize * 20 - overhead); 360 361 addRandomEntry(dropbox, "DropBoxTest2", blockSize * 4 - overhead); 362 addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead); 363 addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead); 364 365 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 366 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 367 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 368 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 369 DropBoxManager.Entry e4 = dropbox.getNextEntry(null, e3.getTimeMillis()); 370 DropBoxManager.Entry e5 = dropbox.getNextEntry(null, e4.getTimeMillis()); 371 DropBoxManager.Entry e6 = dropbox.getNextEntry(null, e5.getTimeMillis()); 372 DropBoxManager.Entry e7 = dropbox.getNextEntry(null, e6.getTimeMillis()); 373 DropBoxManager.Entry e8 = dropbox.getNextEntry(null, e7.getTimeMillis()); 374 DropBoxManager.Entry e9 = dropbox.getNextEntry(null, e8.getTimeMillis()); 375 assertTrue(null == dropbox.getNextEntry(null, e9.getTimeMillis())); 376 377 assertEquals("DropBoxTest0", e0.getTag()); 378 assertEquals("DropBoxTest0", e1.getTag()); 379 assertEquals(blockSize - overhead, getEntrySize(e0)); 380 assertEquals(blockSize - overhead, getEntrySize(e1)); 381 382 assertEquals("DropBoxTest1", e2.getTag()); 383 assertEquals("DropBoxTest1", e3.getTag()); 384 assertEquals("DropBoxTest1", e4.getTag()); 385 assertEquals("DropBoxTest1", e5.getTag()); 386 assertEquals("DropBoxTest1", e6.getTag()); 387 assertEquals(-1, getEntrySize(e2)); // Tombstone 388 assertEquals(blockSize - overhead, getEntrySize(e3)); 389 assertEquals(blockSize * 2 - overhead, getEntrySize(e4)); 390 assertEquals(blockSize - overhead, getEntrySize(e5)); 391 assertEquals(-1, getEntrySize(e6)); 392 393 assertEquals("DropBoxTest2", e7.getTag()); 394 assertEquals("DropBoxTest2", e8.getTag()); 395 assertEquals("DropBoxTest2", e9.getTag()); 396 assertEquals(-1, getEntrySize(e7)); // Tombstone 397 assertEquals(blockSize - overhead, getEntrySize(e8)); 398 assertEquals(blockSize - overhead, getEntrySize(e9)); 399 400 e0.close(); 401 e1.close(); 402 e2.close(); 403 e3.close(); 404 e4.close(); 405 e5.close(); 406 e6.close(); 407 e7.close(); 408 e8.close(); 409 e9.close(); 410 411 // Specifying a tag name skips tombstone records. 412 413 DropBoxManager.Entry t0 = dropbox.getNextEntry("DropBoxTest1", before); 414 DropBoxManager.Entry t1 = dropbox.getNextEntry("DropBoxTest1", t0.getTimeMillis()); 415 DropBoxManager.Entry t2 = dropbox.getNextEntry("DropBoxTest1", t1.getTimeMillis()); 416 assertTrue(null == dropbox.getNextEntry("DropBoxTest1", t2.getTimeMillis())); 417 418 assertEquals("DropBoxTest1", t0.getTag()); 419 assertEquals("DropBoxTest1", t1.getTag()); 420 assertEquals("DropBoxTest1", t2.getTag()); 421 422 assertEquals(blockSize - overhead, getEntrySize(t0)); 423 assertEquals(blockSize * 2 - overhead, getEntrySize(t1)); 424 assertEquals(blockSize - overhead, getEntrySize(t2)); 425 426 t0.close(); 427 t1.close(); 428 t2.close(); 429 } 430 testAgeLimits()431 public void testAgeLimits() throws Exception { 432 File dir = getEmptyDir("testAgeLimits"); 433 int blockSize = new StatFs(dir.getPath()).getBlockSize(); 434 435 // Limit storage to 10 blocks with an expiration of 1 second 436 int kb = blockSize * 10 / 1024; 437 ContentResolver cr = getContext().getContentResolver(); 438 Settings.Global.putString(cr, Settings.Global.DROPBOX_AGE_SECONDS, "1"); 439 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, Integer.toString(kb)); 440 441 // Write one normal entry and another so big that it is instantly tombstoned 442 long before = System.currentTimeMillis(); 443 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 444 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 445 446 dropbox.addText("DropBoxTest", "TEST"); 447 addRandomEntry(dropbox, "DropBoxTest", blockSize * 20); 448 449 // Verify that things are as expected 450 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 451 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 452 assertTrue(null == dropbox.getNextEntry(null, e1.getTimeMillis())); 453 454 assertEquals("TEST", e0.getText(80)); 455 assertEquals(null, e1.getText(80)); 456 assertEquals(-1, getEntrySize(e1)); 457 458 e0.close(); 459 e1.close(); 460 461 // Wait a second and write another entry -- old ones should be expunged 462 Thread.sleep(2000); 463 dropbox.addText("DropBoxTest", "TEST1"); 464 465 e0 = dropbox.getNextEntry(null, before); 466 assertTrue(null == dropbox.getNextEntry(null, e0.getTimeMillis())); 467 assertEquals("TEST1", e0.getText(80)); 468 e0.close(); 469 } 470 testFileCountLimits()471 public void testFileCountLimits() throws Exception { 472 File dir = getEmptyDir("testFileCountLimits"); 473 474 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 475 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 476 dropbox.addText("DropBoxTest", "TEST0"); 477 dropbox.addText("DropBoxTest", "TEST1"); 478 dropbox.addText("DropBoxTest", "TEST2"); 479 dropbox.addText("DropBoxTest", "TEST3"); 480 dropbox.addText("DropBoxTest", "TEST4"); 481 dropbox.addText("DropBoxTest", "TEST5"); 482 483 // Verify 6 files added 484 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, 0); 485 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 486 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 487 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 488 DropBoxManager.Entry e4 = dropbox.getNextEntry(null, e3.getTimeMillis()); 489 DropBoxManager.Entry e5 = dropbox.getNextEntry(null, e4.getTimeMillis()); 490 assertTrue(null == dropbox.getNextEntry(null, e5.getTimeMillis())); 491 assertEquals("TEST0", e0.getText(80)); 492 assertEquals("TEST5", e5.getText(80)); 493 494 e0.close(); 495 e1.close(); 496 e2.close(); 497 e3.close(); 498 e4.close(); 499 e5.close(); 500 501 // Limit to 3 files and add one more entry 502 ContentResolver cr = getContext().getContentResolver(); 503 Settings.Global.putString(cr, Settings.Global.DROPBOX_MAX_FILES, "3"); 504 dropbox.addText("DropBoxTest", "TEST6"); 505 506 // Verify only 3 files left 507 DropBoxManager.Entry f0 = dropbox.getNextEntry(null, 0); 508 DropBoxManager.Entry f1 = dropbox.getNextEntry(null, f0.getTimeMillis()); 509 DropBoxManager.Entry f2 = dropbox.getNextEntry(null, f1.getTimeMillis()); 510 assertTrue(null == dropbox.getNextEntry(null, f2.getTimeMillis())); 511 assertEquals("TEST4", f0.getText(80)); 512 assertEquals("TEST5", f1.getText(80)); 513 assertEquals("TEST6", f2.getText(80)); 514 515 f0.close(); 516 f1.close(); 517 f2.close(); 518 } 519 testCreateDropBoxManagerWithInvalidDirectory()520 public void testCreateDropBoxManagerWithInvalidDirectory() throws Exception { 521 // If created with an invalid directory, the DropBoxManager should suffer quietly 522 // and fail all operations (this is how it survives a full disk). 523 // Once the directory becomes possible to create, it will start working. 524 525 File dir = new File(getEmptyDir("testCreateDropBoxManagerWith"), "InvalidDirectory"); 526 new FileOutputStream(dir).close(); // Create an empty file 527 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 528 DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); 529 530 dropbox.addText("DropBoxTest", "should be ignored"); 531 dropbox.addData("DropBoxTest", "should be ignored".getBytes(), 0); 532 assertTrue(null == dropbox.getNextEntry("DropBoxTest", 0)); 533 534 dir.delete(); // Remove the file so a directory can be created 535 dropbox.addText("DropBoxTest", "TEST"); 536 DropBoxManager.Entry e = dropbox.getNextEntry("DropBoxTest", 0); 537 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e.getTimeMillis())); 538 assertEquals("DropBoxTest", e.getTag()); 539 assertEquals("TEST", e.getText(80)); 540 e.close(); 541 } 542 testDropBoxEntrySerialization()543 public void testDropBoxEntrySerialization() throws Exception { 544 // Make sure DropBoxManager.Entry can be serialized to a Parcel and back 545 // under a variety of conditions. 546 547 Parcel parcel = Parcel.obtain(); 548 File dir = getEmptyDir("testDropBoxEntrySerialization"); 549 550 new DropBoxManager.Entry("empty", 1000000).writeToParcel(parcel, 0); 551 new DropBoxManager.Entry("string", 2000000, "String Value").writeToParcel(parcel, 0); 552 new DropBoxManager.Entry("bytes", 3000000, "Bytes Value".getBytes(), 553 DropBoxManager.IS_TEXT).writeToParcel(parcel, 0); 554 new DropBoxManager.Entry("zerobytes", 4000000, new byte[0], 0).writeToParcel(parcel, 0); 555 new DropBoxManager.Entry("emptybytes", 5000000, (byte[]) null, 556 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 557 558 try { 559 new DropBoxManager.Entry("badbytes", 99999, 560 "Bad Bytes Value".getBytes(), 561 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 562 fail("IllegalArgumentException expected for non-null byte[] and IS_EMPTY flags"); 563 } catch (IllegalArgumentException e) { 564 // expected 565 } 566 567 try { 568 new DropBoxManager.Entry("badbytes", 99999, (byte[]) null, 0).writeToParcel(parcel, 0); 569 fail("IllegalArgumentException expected for null byte[] and non-IS_EMPTY flags"); 570 } catch (IllegalArgumentException e) { 571 // expected 572 } 573 574 File f = new File(dir, "file.dat"); 575 FileOutputStream os = new FileOutputStream(f); 576 os.write("File Value".getBytes()); 577 os.close(); 578 579 new DropBoxManager.Entry("file", 6000000, f, DropBoxManager.IS_TEXT).writeToParcel( 580 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 581 new DropBoxManager.Entry("binfile", 7000000, f, 0).writeToParcel( 582 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 583 new DropBoxManager.Entry("emptyfile", 8000000, (ParcelFileDescriptor) null, 584 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 585 586 try { 587 new DropBoxManager.Entry("badfile", 99999, new File(dir, "nonexist.dat"), 0); 588 fail("IOException expected for nonexistent file"); 589 } catch (IOException e) { 590 // expected 591 } 592 593 try { 594 new DropBoxManager.Entry("badfile", 99999, f, DropBoxManager.IS_EMPTY).writeToParcel( 595 parcel, 0); 596 fail("IllegalArgumentException expected for non-null file and IS_EMPTY flags"); 597 } catch (IllegalArgumentException e) { 598 // expected 599 } 600 601 try { 602 new DropBoxManager.Entry("badfile", 99999, (ParcelFileDescriptor) null, 0); 603 fail("IllegalArgumentException expected for null PFD and non-IS_EMPTY flags"); 604 } catch (IllegalArgumentException e) { 605 // expected 606 } 607 608 File gz = new File(dir, "file.gz"); 609 GZIPOutputStream gzout = new GZIPOutputStream(new FileOutputStream(gz)); 610 gzout.write("Gzip File Value".getBytes()); 611 gzout.close(); 612 613 new DropBoxManager.Entry("gzipfile", 9000000, gz, 614 DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED).writeToParcel( 615 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 616 new DropBoxManager.Entry("gzipbinfile", 10000000, gz, 617 DropBoxManager.IS_GZIPPED).writeToParcel( 618 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 619 620 // 621 // Switch from writing to reading 622 // 623 624 parcel.setDataPosition(0); 625 DropBoxManager.Entry e; 626 627 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 628 assertEquals("empty", e.getTag()); 629 assertEquals(1000000, e.getTimeMillis()); 630 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 631 assertEquals(null, e.getText(100)); 632 assertEquals(null, e.getInputStream()); 633 e.close(); 634 635 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 636 assertEquals("string", e.getTag()); 637 assertEquals(2000000, e.getTimeMillis()); 638 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 639 assertEquals("String Value", e.getText(100)); 640 assertEquals("String Value", 641 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 642 e.close(); 643 644 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 645 assertEquals("bytes", e.getTag()); 646 assertEquals(3000000, e.getTimeMillis()); 647 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 648 assertEquals("Bytes Value", e.getText(100)); 649 e.close(); 650 651 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 652 assertEquals("zerobytes", e.getTag()); 653 assertEquals(4000000, e.getTimeMillis()); 654 assertEquals(0, e.getFlags()); 655 assertEquals(null, e.getText(100)); 656 assertEquals(null, 657 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 658 e.close(); 659 660 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 661 assertEquals("emptybytes", e.getTag()); 662 assertEquals(5000000, e.getTimeMillis()); 663 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 664 assertEquals(null, e.getText(100)); 665 assertEquals(null, e.getInputStream()); 666 e.close(); 667 668 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 669 assertEquals("file", e.getTag()); 670 assertEquals(6000000, e.getTimeMillis()); 671 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 672 assertEquals("File Value", e.getText(100)); 673 e.close(); 674 675 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 676 assertEquals("binfile", e.getTag()); 677 assertEquals(7000000, e.getTimeMillis()); 678 assertEquals(0, e.getFlags()); 679 assertEquals(null, e.getText(100)); 680 assertEquals("File Value", 681 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 682 e.close(); 683 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 684 assertEquals("emptyfile", e.getTag()); 685 assertEquals(8000000, e.getTimeMillis()); 686 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 687 assertEquals(null, e.getText(100)); 688 assertEquals(null, e.getInputStream()); 689 e.close(); 690 691 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 692 assertEquals("gzipfile", e.getTag()); 693 assertEquals(9000000, e.getTimeMillis()); 694 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 695 assertEquals("Gzip File Value", e.getText(100)); 696 e.close(); 697 698 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 699 assertEquals("gzipbinfile", e.getTag()); 700 assertEquals(10000000, e.getTimeMillis()); 701 assertEquals(0, e.getFlags()); 702 assertEquals(null, e.getText(100)); 703 assertEquals("Gzip File Value", 704 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 705 e.close(); 706 assertEquals(0, parcel.dataAvail()); 707 parcel.recycle(); 708 } 709 testDropBoxEntrySerializationDoesntLeakFileDescriptors()710 public void testDropBoxEntrySerializationDoesntLeakFileDescriptors() throws Exception { 711 File dir = getEmptyDir("testDropBoxEntrySerialization"); 712 File f = new File(dir, "file.dat"); 713 FileOutputStream os = new FileOutputStream(f); 714 os.write("File Value".getBytes()); 715 os.close(); 716 717 int before = countOpenFiles(); 718 assertTrue(before > 0); 719 720 for (int i = 0; i < 1000; i++) { 721 Parcel parcel = Parcel.obtain(); 722 new DropBoxManager.Entry("file", 1000000, f, 0).writeToParcel( 723 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 724 725 parcel.setDataPosition(0); 726 DropBoxManager.Entry e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 727 assertEquals("file", e.getTag()); 728 e.close(); 729 730 parcel.recycle(); 731 } 732 733 int after = countOpenFiles(); 734 assertTrue(after > 0); 735 assertTrue(after < before + 20); 736 } 737 738 private void addRandomEntry(DropBoxManager dropbox, String tag, int size) throws Exception { 739 byte[] bytes = new byte[size]; 740 new Random(System.currentTimeMillis()).nextBytes(bytes); 741 742 File f = new File(getEmptyDir("addRandomEntry"), "random.dat"); 743 FileOutputStream os = new FileOutputStream(f); 744 os.write(bytes); 745 os.close(); 746 747 dropbox.addFile(tag, f, 0); 748 } 749 750 private int getEntrySize(DropBoxManager.Entry e) throws Exception { 751 InputStream is = e.getInputStream(); 752 if (is == null) return -1; 753 int length = 0; 754 while (is.read() != -1) length++; 755 return length; 756 } 757 758 private void recursiveDelete(File file) { 759 if (!file.delete() && file.isDirectory()) { 760 for (File f : file.listFiles()) recursiveDelete(f); 761 file.delete(); 762 } 763 } 764 765 private File getEmptyDir(String name) { 766 File dir = getContext().getDir("DropBoxTest." + name, 0); 767 for (File f : dir.listFiles()) recursiveDelete(f); 768 assertTrue(dir.listFiles().length == 0); 769 return dir; 770 } 771 772 private int countOpenFiles() { 773 return new File("/proc/" + Process.myPid() + "/fd").listFiles().length; 774 } 775 } 776