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