Home | History | Annotate | Download | only in server
      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 {
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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