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