Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2006 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 android.content.pm;
     18 
     19 import android.app.PendingIntent;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.os.RemoteException;
     25 import android.os.ServiceManager;
     26 import android.os.StatFs;
     27 import android.test.AndroidTestCase;
     28 import android.test.suitebuilder.annotation.LargeTest;
     29 import android.test.suitebuilder.annotation.MediumTest;
     30 import android.test.suitebuilder.annotation.SmallTest;
     31 import android.util.Log;
     32 
     33 import java.io.File;
     34 import java.io.FileInputStream;
     35 import java.io.FileNotFoundException;
     36 import java.io.FileOutputStream;
     37 import java.io.IOException;
     38 
     39 public class AppCacheTest extends AndroidTestCase {
     40     private static final boolean localLOGV = false;
     41     public static final String TAG="AppCacheTest";
     42     public final long MAX_WAIT_TIME=60*1000;
     43     public final long WAIT_TIME_INCR=10*1000;
     44     private static final int THRESHOLD=5;
     45     private static final int ACTUAL_THRESHOLD=10;
     46 
     47     @Override
     48     protected void setUp() throws Exception {
     49         super.setUp();
     50         if(localLOGV) Log.i(TAG, "Cleaning up cache directory first");
     51         cleanUpCacheDirectory();
     52     }
     53 
     54     void cleanUpDirectory(File pDir, String dirName) {
     55        File testDir = new File(pDir,  dirName);
     56        if(!testDir.exists()) {
     57            return;
     58        }
     59         String fList[] = testDir.list();
     60         for(int i = 0; i < fList.length; i++) {
     61             File file = new File(testDir, fList[i]);
     62             if(file.isDirectory()) {
     63                 cleanUpDirectory(testDir, fList[i]);
     64             } else {
     65                 file.delete();
     66             }
     67         }
     68         testDir.delete();
     69     }
     70 
     71     void cleanUpCacheDirectory() {
     72         File testDir = mContext.getCacheDir();
     73         if(!testDir.exists()) {
     74             return;
     75         }
     76 
     77          String fList[] = testDir.list();
     78          if(fList == null) {
     79              testDir.delete();
     80              return;
     81          }
     82          for(int i = 0; i < fList.length; i++) {
     83              File file = new File(testDir, fList[i]);
     84              if(file.isDirectory()) {
     85                  cleanUpDirectory(testDir, fList[i]);
     86              } else {
     87                  file.delete();
     88              }
     89          }
     90      }
     91 
     92     @SmallTest
     93     public void testDeleteAllCacheFiles() {
     94         String testName="testDeleteAllCacheFiles";
     95         cleanUpCacheDirectory();
     96     }
     97 
     98     void failStr(String errMsg) {
     99         Log.w(TAG, "errMsg="+errMsg);
    100         fail(errMsg);
    101     }
    102     void failStr(Exception e) {
    103         Log.w(TAG, "e.getMessage="+e.getMessage());
    104         Log.w(TAG, "e="+e);
    105     }
    106     long getFreeStorageBlks(StatFs st) {
    107         st.restat("/data");
    108         return st.getFreeBlocks();
    109     }
    110 
    111     long getFreeStorageSize(StatFs st) {
    112         st.restat("/data");
    113         return (st.getFreeBlocks()*st.getBlockSize());
    114     }
    115     @LargeTest
    116     public void testFreeApplicationCacheAllFiles() throws Exception {
    117         boolean TRACKING = true;
    118         StatFs st = new StatFs("/data");
    119         long blks1 = getFreeStorageBlks(st);
    120         long availableMem = getFreeStorageSize(st);
    121         File cacheDir = mContext.getCacheDir();
    122         assertNotNull(cacheDir);
    123         createTestFiles1(cacheDir, "testtmpdir", 5);
    124         long blks2 = getFreeStorageBlks(st);
    125         if(localLOGV || TRACKING) Log.i(TAG, "blk1="+blks1+", blks2="+blks2);
    126         //this should free up the test files that were created earlier
    127         invokePMFreeApplicationCache(availableMem);
    128         long blks3 = getFreeStorageBlks(st);
    129         if(localLOGV || TRACKING) Log.i(TAG, "blks3="+blks3);
    130         verifyTestFiles1(cacheDir, "testtmpdir", 5);
    131     }
    132 
    133     public void testFreeApplicationCacheSomeFiles() throws Exception {
    134         StatFs st = new StatFs("/data");
    135         long blks1 = getFreeStorageBlks(st);
    136         File cacheDir = mContext.getCacheDir();
    137         assertNotNull(cacheDir);
    138         createTestFiles1(cacheDir, "testtmpdir", 5);
    139         long blks2 = getFreeStorageBlks(st);
    140         Log.i(TAG, "blk1="+blks1+", blks2="+blks2);
    141         long diff = (blks1-blks2-2);
    142         assertTrue(invokePMFreeApplicationCache(diff*st.getBlockSize()));
    143         long blks3 = getFreeStorageBlks(st);
    144         //blks3 should be greater than blks2 and less than blks1
    145         if(!((blks3 <= blks1) && (blks3 >= blks2))) {
    146             failStr("Expected "+(blks1-blks2)+" number of blocks to be freed but freed only "
    147                     +(blks1-blks3));
    148         }
    149     }
    150 
    151     /**
    152      * This method opens an output file writes to it, opens the same file as an input
    153      * stream, reads the contents and verifies the data that was written earlier can be read
    154      */
    155     public void openOutFileInAppFilesDir(File pFile, String pFileOut) {
    156         FileOutputStream fos = null;
    157         try {
    158             fos = new FileOutputStream(pFile);
    159         } catch (FileNotFoundException e1) {
    160             failStr("Error when opening file "+e1);
    161             return;
    162         }
    163         try {
    164             fos.write(pFileOut.getBytes());
    165             fos.close();
    166         } catch (FileNotFoundException e) {
    167             failStr(e.getMessage());
    168         } catch (IOException e) {
    169             failStr(e.getMessage());
    170         }
    171         int count = pFileOut.getBytes().length;
    172         byte[] buffer = new byte[count];
    173         try {
    174             FileInputStream fis = new FileInputStream(pFile);
    175             fis.read(buffer, 0, count);
    176             fis.close();
    177         } catch (FileNotFoundException e) {
    178             failStr("Failed when verifing output opening file "+e.getMessage());
    179         } catch (IOException e) {
    180             failStr("Failed when verifying output, reading from written file "+e);
    181         }
    182         String str = new String(buffer);
    183         assertEquals(str, pFileOut);
    184     }
    185 
    186     /*
    187      * This test case verifies that output written to a file
    188      * using Context.openFileOutput has executed successfully.
    189      * The operation is verified by invoking Context.openFileInput
    190      */
    191     @MediumTest
    192     public void testAppFilesCreateFile() {
    193         String fileName = "testFile1.txt";
    194         String fileOut = "abcdefghijklmnopqrstuvwxyz";
    195         Context con = super.getContext();
    196         try {
    197             FileOutputStream fos = con.openFileOutput(fileName, Context.MODE_PRIVATE);
    198             fos.close();
    199         } catch (FileNotFoundException e) {
    200             failStr(e);
    201         } catch (IOException e) {
    202             failStr(e);
    203         }
    204     }
    205 
    206     @SmallTest
    207     public void testAppCacheCreateFile() {
    208         String fileName = "testFile1.txt";
    209         String fileOut = "abcdefghijklmnopqrstuvwxyz";
    210         Context con = super.getContext();
    211         File file = new File(con.getCacheDir(), fileName);
    212         openOutFileInAppFilesDir(file, fileOut);
    213         cleanUpCacheDirectory();
    214     }
    215 
    216     @MediumTest
    217     public void testAppCreateCacheFiles() {
    218         File cacheDir = mContext.getCacheDir();
    219         String testDirName = "testtmp";
    220         File testTmpDir = new File(cacheDir, testDirName);
    221         testTmpDir.mkdir();
    222         int numDirs = 3;
    223         File fileArr[] = new File[numDirs];
    224         for(int i = 0; i < numDirs; i++) {
    225             fileArr[i] = new File(testTmpDir, "dir"+(i+1));
    226             fileArr[i].mkdir();
    227         }
    228         byte buffer[] = getBuffer();
    229         Log.i(TAG, "Size of bufer="+buffer.length);
    230         for(int i = 0; i < numDirs; i++) {
    231             for(int j = 1; j <= (i); j++) {
    232                 File file1 = new File(fileArr[i], "testFile"+j+".txt");
    233                 FileOutputStream fos = null;
    234                 try {
    235                     fos = new FileOutputStream(file1);
    236                     for(int k = 1; k < 10; k++) {
    237                         fos.write(buffer);
    238                     }
    239                     Log.i(TAG, "wrote 10K bytes to "+file1);
    240                     fos.close();
    241                 } catch (FileNotFoundException e) {
    242                     Log.i(TAG, "Excetion ="+e);
    243                     fail("Error when creating outputstream "+e);
    244                 } catch(IOException e) {
    245                     Log.i(TAG, "Excetion ="+e);
    246                     fail("Error when writing output "+e);
    247                 }
    248             }
    249         }
    250     }
    251 
    252     byte[] getBuffer() {
    253         String sbuffer = "a";
    254         for(int i = 0; i < 10; i++) {
    255             sbuffer += sbuffer;
    256         }
    257         return sbuffer.getBytes();
    258     }
    259 
    260     long getFileNumBlocks(long fileSize, int blkSize) {
    261         long ret = fileSize/blkSize;
    262         if(ret*blkSize < fileSize) {
    263             ret++;
    264         }
    265         return ret;
    266     }
    267 
    268     //@LargeTest
    269     public void testAppCacheClear() {
    270         String dataDir="/data/data";
    271         StatFs st = new StatFs(dataDir);
    272         int blkSize = st.getBlockSize();
    273         int totBlks = st.getBlockCount();
    274         long availableBlks = st.getFreeBlocks();
    275         long thresholdBlks = (totBlks*THRESHOLD)/100;
    276         String testDirName = "testdir";
    277         //create directory in cache
    278         File testDir = new File(mContext.getCacheDir(),  testDirName);
    279         testDir.mkdirs();
    280         byte[] buffer = getBuffer();
    281         int i = 1;
    282         if(localLOGV) Log.i(TAG, "availableBlks="+availableBlks+", thresholdBlks="+thresholdBlks);
    283         long createdFileBlks = 0;
    284         int imax = 300;
    285         while((availableBlks > thresholdBlks) &&(i < imax)) {
    286             File testFile = new File(testDir, "testFile"+i+".txt");
    287             if(localLOGV) Log.i(TAG, "Creating "+i+"th test file "+testFile);
    288             int jmax = i;
    289             i++;
    290             FileOutputStream fos;
    291             try {
    292                 fos = new FileOutputStream(testFile);
    293             } catch (FileNotFoundException e) {
    294                 Log.i(TAG, "Failed creating test file:"+testFile);
    295                 continue;
    296             }
    297             boolean err = false;
    298             for(int j = 1; j <= jmax;j++) {
    299                 try {
    300                     fos.write(buffer);
    301                 } catch (IOException e) {
    302                     Log.i(TAG, "Failed to write to file:"+testFile);
    303                     err = true;
    304                 }
    305             }
    306             try {
    307                 fos.close();
    308             } catch (IOException e) {
    309                 Log.i(TAG, "Failed closing file:"+testFile);
    310             }
    311             if(err) {
    312                 continue;
    313             }
    314             createdFileBlks += getFileNumBlocks(testFile.length(), blkSize);
    315             st.restat(dataDir);
    316             availableBlks = st.getFreeBlocks();
    317         }
    318         st.restat(dataDir);
    319         long availableBytes = st.getFreeBlocks()*blkSize;
    320         long shouldFree = (ACTUAL_THRESHOLD-THRESHOLD)*totBlks;
    321         //would have run out of memory
    322         //wait for some time and confirm cache is deleted
    323         try {
    324             Log.i(TAG, "Sleeping for 2 minutes...");
    325             Thread.sleep(2*60*1000);
    326         } catch (InterruptedException e) {
    327             fail("Exception when sleeping "+e);
    328         }
    329         boolean removedFlag = false;
    330         long existingFileBlks = 0;
    331         for(int k = 1; k <i; k++) {
    332             File testFile = new File(testDir, "testFile"+k+".txt");
    333             if(!testFile.exists()) {
    334                 removedFlag = true;
    335                 if(localLOGV) Log.i(TAG, testFile+" removed");
    336             }  else {
    337                 existingFileBlks += getFileNumBlocks(testFile.length(), blkSize);
    338             }
    339         }
    340         if(localLOGV) Log.i(TAG, "createdFileBlks="+createdFileBlks+
    341                 ", existingFileBlks="+existingFileBlks);
    342         long fileSize = createdFileBlks-existingFileBlks;
    343         //verify fileSize number of bytes have been cleared from cache
    344         if(localLOGV) Log.i(TAG, "deletedFileBlks="+fileSize+" shouldFreeBlks="+shouldFree);
    345         if((fileSize > (shouldFree-blkSize) && (fileSize < (shouldFree+blkSize)))) {
    346             Log.i(TAG, "passed");
    347         }
    348         assertTrue(removedFlag);
    349     }
    350 
    351     //createTestFiles(new File(super.getContext().getCacheDir(), "testtmp", "dir", 3)
    352     void createTestFiles1(File cacheDir, String testFilePrefix, int numTestFiles) {
    353         byte buffer[] = getBuffer();
    354         for(int i = 0; i < numTestFiles; i++) {
    355             File file1 = new File(cacheDir, testFilePrefix+i+".txt");
    356             FileOutputStream fos = null;
    357             try {
    358                 fos = new FileOutputStream(file1);
    359                 for(int k = 1; k < 10; k++) {
    360                     fos.write(buffer);
    361                }
    362                 fos.close();
    363             } catch (FileNotFoundException e) {
    364                 Log.i(TAG, "Exception ="+e);
    365                 fail("Error when creating outputstream "+e);
    366             } catch(IOException e) {
    367                 Log.i(TAG, "Exception ="+e);
    368                 fail("Error when writing output "+e);
    369             }
    370             try {
    371                 //introduce sleep for 1 s to avoid common time stamps for files being created
    372                 Thread.sleep(1000);
    373             } catch (InterruptedException e) {
    374                 fail("Exception when sleeping "+e);
    375             }
    376         }
    377     }
    378 
    379     void verifyTestFiles1(File cacheDir, String testFilePrefix, int numTestFiles) {
    380         for(int i = 0; i < numTestFiles; i++) {
    381             File file1 = new File(cacheDir, testFilePrefix+i+".txt");
    382             if(file1.exists()) {
    383                 fail("file:"+file1+" should not exist");
    384             }
    385         }
    386     }
    387 
    388     void createTestFiles2(File cacheDir, String rootTestDirName, String subDirPrefix, int numDirs, String testFilePrefix) {
    389         Context con = super.getContext();
    390         File testTmpDir = new File(cacheDir, rootTestDirName);
    391         testTmpDir.mkdir();
    392         File fileArr[] = new File[numDirs];
    393         for(int i = 0; i < numDirs; i++) {
    394             fileArr[i] = new File(testTmpDir, subDirPrefix+(i+1));
    395             fileArr[i].mkdir();
    396         }
    397         byte buffer[] = getBuffer();
    398         for(int i = 0; i < numDirs; i++) {
    399             for(int j = 1; j <= (i); j++) {
    400                 File file1 = new File(fileArr[i], testFilePrefix+j+".txt");
    401                 FileOutputStream fos = null;
    402                 try {
    403                     fos = new FileOutputStream(file1);
    404                     for(int k = 1; k < 10; k++) {
    405                         fos.write(buffer);
    406                     }
    407                     fos.close();
    408                 } catch (FileNotFoundException e) {
    409                     Log.i(TAG, "Exception ="+e);
    410                     fail("Error when creating outputstream "+e);
    411                 } catch(IOException e) {
    412                     Log.i(TAG, "Exception ="+e);
    413                     fail("Error when writing output "+e);
    414                 }
    415                 try {
    416                     //introduce sleep for 10 ms to avoid common time stamps for files being created
    417                     Thread.sleep(10);
    418                 } catch (InterruptedException e) {
    419                     fail("Exception when sleeping "+e);
    420                 }
    421             }
    422         }
    423     }
    424 
    425     class PackageDataObserver extends IPackageDataObserver.Stub {
    426         public boolean retValue = false;
    427         private boolean doneFlag = false;
    428         public void onRemoveCompleted(String packageName, boolean succeeded)
    429                 throws RemoteException {
    430             synchronized(this) {
    431                 retValue = succeeded;
    432                 doneFlag = true;
    433                 notifyAll();
    434             }
    435         }
    436         public boolean isDone() {
    437             return doneFlag;
    438         }
    439     }
    440 
    441     IPackageManager getPm() {
    442         return  IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
    443     }
    444 
    445     boolean invokePMDeleteAppCacheFiles() throws Exception {
    446         try {
    447             String packageName = mContext.getPackageName();
    448             PackageDataObserver observer = new PackageDataObserver();
    449             //wait on observer
    450             synchronized(observer) {
    451                 getPm().deleteApplicationCacheFiles(packageName, observer);
    452                 long waitTime = 0;
    453                 while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) {
    454                     observer.wait(WAIT_TIME_INCR);
    455                     waitTime += WAIT_TIME_INCR;
    456                 }
    457                 if(!observer.isDone()) {
    458                     throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted");
    459                 }
    460             }
    461             return observer.retValue;
    462         } catch (RemoteException e) {
    463             Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
    464             return false;
    465         } catch (InterruptedException e) {
    466             Log.w(TAG, "InterruptedException :"+e);
    467             return false;
    468         }
    469     }
    470 
    471     boolean invokePMFreeApplicationCache(long idealStorageSize) throws Exception {
    472         try {
    473             String packageName = mContext.getPackageName();
    474             PackageDataObserver observer = new PackageDataObserver();
    475             //wait on observer
    476             synchronized(observer) {
    477                 getPm().freeStorageAndNotify(idealStorageSize, observer);
    478                 long waitTime = 0;
    479                 while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) {
    480                     observer.wait(WAIT_TIME_INCR);
    481                     waitTime += WAIT_TIME_INCR;
    482                 }
    483                 if(!observer.isDone()) {
    484                     throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted");
    485                 }
    486             }
    487             return observer.retValue;
    488         } catch (RemoteException e) {
    489             Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
    490             return false;
    491         } catch (InterruptedException e) {
    492             Log.w(TAG, "InterruptedException :"+e);
    493             return false;
    494         }
    495     }
    496 
    497     boolean invokePMFreeStorage(long idealStorageSize, FreeStorageReceiver r,
    498             PendingIntent pi) throws Exception {
    499         try {
    500             // Spin lock waiting for call back
    501             synchronized(r) {
    502                 getPm().freeStorage(idealStorageSize, pi.getIntentSender());
    503                 long waitTime = 0;
    504                 while(!r.isDone() && (waitTime < MAX_WAIT_TIME)) {
    505                     r.wait(WAIT_TIME_INCR);
    506                     waitTime += WAIT_TIME_INCR;
    507                 }
    508                 if(!r.isDone()) {
    509                     throw new Exception("timed out waiting for call back from PendingIntent");
    510                 }
    511             }
    512             return r.getResultCode() == 1;
    513         } catch (RemoteException e) {
    514             Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
    515             return false;
    516         } catch (InterruptedException e) {
    517             Log.w(TAG, "InterruptedException :"+e);
    518             return false;
    519         }
    520     }
    521 
    522     @LargeTest
    523     public void testDeleteAppCacheFiles() throws Exception {
    524         String testName="testDeleteAppCacheFiles";
    525         File cacheDir = mContext.getCacheDir();
    526         createTestFiles1(cacheDir, "testtmpdir", 5);
    527         assertTrue(invokePMDeleteAppCacheFiles());
    528         //confirm files dont exist
    529         verifyTestFiles1(cacheDir, "testtmpdir", 5);
    530     }
    531 
    532     class PackageStatsObserver extends IPackageStatsObserver.Stub {
    533         public boolean retValue = false;
    534         public PackageStats stats;
    535         private boolean doneFlag = false;
    536 
    537         public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
    538                 throws RemoteException {
    539             synchronized(this) {
    540                 retValue = succeeded;
    541                 stats = pStats;
    542                 doneFlag = true;
    543                 notifyAll();
    544             }
    545         }
    546         public boolean isDone() {
    547             return doneFlag;
    548         }
    549     }
    550 
    551     public PackageStats invokePMGetPackageSizeInfo() throws Exception {
    552         try {
    553             String packageName = mContext.getPackageName();
    554             PackageStatsObserver observer = new PackageStatsObserver();
    555             //wait on observer
    556             synchronized(observer) {
    557                 getPm().getPackageSizeInfo(packageName, observer);
    558                 long waitTime = 0;
    559                 while((!observer.isDone()) || (waitTime > MAX_WAIT_TIME) ) {
    560                     observer.wait(WAIT_TIME_INCR);
    561                     waitTime += WAIT_TIME_INCR;
    562                 }
    563                 if(!observer.isDone()) {
    564                     throw new Exception("Timed out waiting for PackageStatsObserver.onGetStatsCompleted");
    565                 }
    566             }
    567             if(localLOGV) Log.i(TAG, "OBSERVER RET VALUES code="+observer.stats.codeSize+
    568                     ", data="+observer.stats.dataSize+", cache="+observer.stats.cacheSize);
    569             return observer.stats;
    570         } catch (RemoteException e) {
    571             Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
    572             return null;
    573         } catch (InterruptedException e) {
    574             Log.w(TAG, "InterruptedException :"+e);
    575             return null;
    576         }
    577     }
    578 
    579     @SmallTest
    580     public void testGetPackageSizeInfo() throws Exception {
    581         String testName="testGetPackageSizeInfo";
    582         PackageStats stats = invokePMGetPackageSizeInfo();
    583         assertTrue(stats!=null);
    584         //confirm result
    585         if(localLOGV) Log.i(TAG, "code="+stats.codeSize+", data="+stats.dataSize+
    586                 ", cache="+stats.cacheSize);
    587     }
    588 
    589     @SmallTest
    590     public void testGetSystemSharedLibraryNames() throws Exception {
    591         try {
    592             String[] sharedLibs = getPm().getSystemSharedLibraryNames();
    593             if (localLOGV) {
    594                 for (String str : sharedLibs) {
    595                     Log.i(TAG, str);
    596                 }
    597             }
    598         } catch (RemoteException e) {
    599             fail("Failed invoking getSystemSharedLibraryNames with exception:" + e);
    600         }
    601     }
    602 
    603     class FreeStorageReceiver extends BroadcastReceiver {
    604         public static final String ACTION_FREE = "com.android.unit_tests.testcallback";
    605         private boolean doneFlag = false;
    606 
    607         public boolean isDone() {
    608             return doneFlag;
    609         }
    610 
    611         @Override
    612         public void onReceive(Context context, Intent intent) {
    613             if(intent.getAction().equalsIgnoreCase(ACTION_FREE)) {
    614                 if (localLOGV) Log.i(TAG, "Got notification: clear cache succeeded "+getResultCode());
    615                 synchronized (this) {
    616                     doneFlag = true;
    617                     notifyAll();
    618                 }
    619             }
    620         }
    621     }
    622 
    623     // TODO: flaky test, omit from LargeTest for now
    624     //@LargeTest
    625     public void testFreeStorage() throws Exception {
    626         boolean TRACKING = true;
    627         StatFs st = new StatFs("/data");
    628         long blks1 = getFreeStorageBlks(st);
    629         if(localLOGV || TRACKING) Log.i(TAG, "Available free blocks="+blks1);
    630         long availableMem = getFreeStorageSize(st);
    631         File cacheDir = mContext.getCacheDir();
    632         assertNotNull(cacheDir);
    633         createTestFiles1(cacheDir, "testtmpdir", 5);
    634         long blks2 = getFreeStorageBlks(st);
    635         if(localLOGV || TRACKING) Log.i(TAG, "Available blocks after writing test files in application cache="+blks2);
    636         // Create receiver and register it
    637         FreeStorageReceiver receiver = new FreeStorageReceiver();
    638         mContext.registerReceiver(receiver, new IntentFilter(FreeStorageReceiver.ACTION_FREE));
    639         PendingIntent pi = PendingIntent.getBroadcast(mContext,
    640                 0,  new Intent(FreeStorageReceiver.ACTION_FREE), 0);
    641         // Invoke PackageManager api
    642         invokePMFreeStorage(availableMem, receiver, pi);
    643         long blks3 = getFreeStorageBlks(st);
    644         if(localLOGV || TRACKING) Log.i(TAG, "Available blocks after freeing cache"+blks3);
    645         assertEquals(receiver.getResultCode(), 1);
    646         mContext.unregisterReceiver(receiver);
    647         // Verify result
    648         verifyTestFiles1(cacheDir, "testtmpdir", 5);
    649     }
    650 
    651     /* utility method used to create observer and check async call back from PackageManager.
    652      * ClearApplicationUserData
    653      */
    654     boolean invokePMClearApplicationUserData() throws Exception {
    655         try {
    656             String packageName = mContext.getPackageName();
    657             PackageDataObserver observer = new PackageDataObserver();
    658             //wait on observer
    659             synchronized(observer) {
    660                 getPm().clearApplicationUserData(packageName, observer);
    661                 long waitTime = 0;
    662                 while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) {
    663                     observer.wait(WAIT_TIME_INCR);
    664                     waitTime += WAIT_TIME_INCR;
    665                 }
    666                 if(!observer.isDone()) {
    667                     throw new Exception("timed out waiting for PackageDataObserver.onRemoveCompleted");
    668                 }
    669             }
    670             return observer.retValue;
    671         } catch (RemoteException e) {
    672             Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
    673             return false;
    674         } catch (InterruptedException e) {
    675             Log.w(TAG, "InterruptedException :"+e);
    676             return false;
    677         }
    678     }
    679 
    680     void verifyUserDataCleared(File pDir) {
    681         if(localLOGV) Log.i(TAG, "Verifying "+pDir);
    682         if(pDir == null) {
    683             return;
    684         }
    685         String fileList[] = pDir.list();
    686         if(fileList == null) {
    687             return;
    688         }
    689         int imax = fileList.length;
    690        //look recursively in user data dir
    691         for(int i = 0; i < imax; i++) {
    692             if(localLOGV) Log.i(TAG, "Found entry "+fileList[i]+ "in "+pDir);
    693             if("lib".equalsIgnoreCase(fileList[i])) {
    694                 if(localLOGV) Log.i(TAG, "Ignoring lib directory");
    695                 continue;
    696             }
    697             fail(pDir+" should be empty or contain only lib subdirectory. Found "+fileList[i]);
    698         }
    699     }
    700 
    701     File getDataDir() {
    702         try {
    703             ApplicationInfo appInfo = getPm().getApplicationInfo(mContext.getPackageName(), 0);
    704             return new File(appInfo.dataDir);
    705         } catch (RemoteException e) {
    706             throw new RuntimeException("Pacakge manager dead", e);
    707         }
    708     }
    709 
    710     @LargeTest
    711     public void testClearApplicationUserDataWithTestData() throws Exception {
    712         File cacheDir = mContext.getCacheDir();
    713         createTestFiles1(cacheDir, "testtmpdir", 5);
    714         if(localLOGV) {
    715             Log.i(TAG, "Created test data Waiting for 60seconds before continuing");
    716             Thread.sleep(60*1000);
    717         }
    718         assertTrue(invokePMClearApplicationUserData());
    719         //confirm files dont exist
    720         verifyUserDataCleared(getDataDir());
    721     }
    722 
    723     @SmallTest
    724     public void testClearApplicationUserDataWithNoTestData() throws Exception {
    725         assertTrue(invokePMClearApplicationUserData());
    726         //confirm files dont exist
    727         verifyUserDataCleared(getDataDir());
    728     }
    729 
    730     @LargeTest
    731     public void testClearApplicationUserDataNoObserver() throws Exception {
    732         getPm().clearApplicationUserData(mContext.getPackageName(), null);
    733         //sleep for 1 minute
    734         Thread.sleep(60*1000);
    735         //confirm files dont exist
    736         verifyUserDataCleared(getDataDir());
    737     }
    738 
    739 }
    740