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