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 static android.system.OsConstants.S_IFDIR;
20 import static android.system.OsConstants.S_IFMT;
21 import static android.system.OsConstants.S_IRGRP;
22 import static android.system.OsConstants.S_IROTH;
23 import static android.system.OsConstants.S_IRWXU;
24 import static android.system.OsConstants.S_ISDIR;
25 import static android.system.OsConstants.S_IXGRP;
26 import static android.system.OsConstants.S_IXOTH;
27 
28 import android.app.PackageInstallObserver;
29 import android.content.BroadcastReceiver;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.IntentFilter;
33 import android.content.pm.PackageManager.NameNotFoundException;
34 import android.content.pm.PackageParser.PackageParserException;
35 import android.content.res.Resources;
36 import android.content.res.Resources.NotFoundException;
37 import android.net.Uri;
38 import android.os.Binder;
39 import android.os.Bundle;
40 import android.os.Environment;
41 import android.os.FileUtils;
42 import android.os.IBinder;
43 import android.os.Process;
44 import android.os.RemoteException;
45 import android.os.ServiceManager;
46 import android.os.StatFs;
47 import android.os.SystemClock;
48 import android.os.UserManager;
49 import android.os.storage.IMountService;
50 import android.os.storage.StorageListener;
51 import android.os.storage.StorageManager;
52 import android.os.storage.StorageResultCode;
53 import android.provider.Settings;
54 import android.provider.Settings.SettingNotFoundException;
55 import android.system.ErrnoException;
56 import android.system.Os;
57 import android.system.StructStat;
58 import android.test.AndroidTestCase;
59 import android.test.suitebuilder.annotation.LargeTest;
60 import android.test.suitebuilder.annotation.SmallTest;
61 import android.test.suitebuilder.annotation.Suppress;
62 import android.util.Log;
63 
64 import com.android.frameworks.coretests.R;
65 import com.android.internal.content.PackageHelper;
66 
67 import java.io.File;
68 import java.io.IOException;
69 import java.io.InputStream;
70 import java.util.HashSet;
71 import java.util.List;
72 import java.util.Set;
73 import java.util.concurrent.CountDownLatch;
74 import java.util.concurrent.TimeUnit;
75 
76 public class PackageManagerTests extends AndroidTestCase {
77     private static final boolean localLOGV = true;
78 
79     public static final String TAG = "PackageManagerTests";
80 
81     public final long MAX_WAIT_TIME = 25 * 1000;
82 
83     public final long WAIT_TIME_INCR = 5 * 1000;
84 
85     private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
86 
87     private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
88 
89     private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
90 
91     private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL;
92 
93     private boolean mOrigState;
94 
failStr(String errMsg)95     void failStr(String errMsg) {
96         Log.w(TAG, "errMsg=" + errMsg);
97         fail(errMsg);
98     }
99 
failStr(Exception e)100     void failStr(Exception e) {
101         failStr(e.getMessage());
102     }
103 
104     @Override
setUp()105     protected void setUp() throws Exception {
106         super.setUp();
107         mOrigState = checkMediaState(Environment.MEDIA_MOUNTED);
108         if (!mountMedia()) {
109             Log.i(TAG, "sdcard not mounted? Some of these tests might fail");
110         }
111     }
112 
113     @Override
tearDown()114     protected void tearDown() throws Exception {
115         // Restore media state.
116         boolean newState = checkMediaState(Environment.MEDIA_MOUNTED);
117         if (newState != mOrigState) {
118             if (mOrigState) {
119                 mountMedia();
120             } else {
121                 unmountMedia();
122             }
123         }
124         super.tearDown();
125     }
126 
127     private class TestInstallObserver extends PackageInstallObserver {
128         public int returnCode;
129 
130         private boolean doneFlag = false;
131 
132         @Override
onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras)133         public void onPackageInstalled(String basePackageName, int returnCode, String msg,
134                 Bundle extras) {
135             Log.d(TAG, "onPackageInstalled: code=" + returnCode + ", msg=" + msg + ", extras="
136                     + extras);
137             synchronized (this) {
138                 this.returnCode = returnCode;
139                 doneFlag = true;
140                 notifyAll();
141             }
142         }
143 
isDone()144         public boolean isDone() {
145             return doneFlag;
146         }
147     }
148 
149     abstract class GenericReceiver extends BroadcastReceiver {
150         private boolean doneFlag = false;
151 
152         boolean received = false;
153 
154         Intent intent;
155 
156         IntentFilter filter;
157 
notifyNow(Intent intent)158         abstract boolean notifyNow(Intent intent);
159 
160         @Override
onReceive(Context context, Intent intent)161         public void onReceive(Context context, Intent intent) {
162             if (notifyNow(intent)) {
163                 synchronized (this) {
164                     received = true;
165                     doneFlag = true;
166                     this.intent = intent;
167                     notifyAll();
168                 }
169             }
170         }
171 
isDone()172         public boolean isDone() {
173             return doneFlag;
174         }
175 
setFilter(IntentFilter filter)176         public void setFilter(IntentFilter filter) {
177             this.filter = filter;
178         }
179     }
180 
181     class InstallReceiver extends GenericReceiver {
182         String pkgName;
183 
InstallReceiver(String pkgName)184         InstallReceiver(String pkgName) {
185             this.pkgName = pkgName;
186             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
187             filter.addDataScheme("package");
188             super.setFilter(filter);
189         }
190 
notifyNow(Intent intent)191         public boolean notifyNow(Intent intent) {
192             String action = intent.getAction();
193             if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) {
194                 return false;
195             }
196             Uri data = intent.getData();
197             String installedPkg = data.getEncodedSchemeSpecificPart();
198             if (pkgName.equals(installedPkg)) {
199                 return true;
200             }
201             return false;
202         }
203     }
204 
getPm()205     private PackageManager getPm() {
206         return mContext.getPackageManager();
207     }
208 
getIPm()209     private IPackageManager getIPm() {
210         IPackageManager ipm  = IPackageManager.Stub.asInterface(
211                 ServiceManager.getService("package"));
212         return ipm;
213     }
214 
invokeInstallPackage(Uri packageURI, int flags, GenericReceiver receiver, boolean shouldSucceed)215     public void invokeInstallPackage(Uri packageURI, int flags, GenericReceiver receiver,
216             boolean shouldSucceed) {
217         TestInstallObserver observer = new TestInstallObserver();
218         mContext.registerReceiver(receiver, receiver.filter);
219         try {
220             // Wait on observer
221             synchronized (observer) {
222                 synchronized (receiver) {
223                     getPm().installPackage(packageURI, observer, flags, null);
224                     long waitTime = 0;
225                     while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
226                         try {
227                             observer.wait(WAIT_TIME_INCR);
228                             waitTime += WAIT_TIME_INCR;
229                         } catch (InterruptedException e) {
230                             Log.i(TAG, "Interrupted during sleep", e);
231                         }
232                     }
233                     if (!observer.isDone()) {
234                         fail("Timed out waiting for packageInstalled callback");
235                     }
236 
237                     if (shouldSucceed) {
238                         if (observer.returnCode != PackageManager.INSTALL_SUCCEEDED) {
239                             fail("Package installation should have succeeded, but got code "
240                                     + observer.returnCode);
241                         }
242                     } else {
243                         if (observer.returnCode == PackageManager.INSTALL_SUCCEEDED) {
244                             fail("Package installation should fail");
245                         }
246 
247                         /*
248                          * We'll never expect get a notification since we
249                          * shouldn't succeed.
250                          */
251                         return;
252                     }
253 
254                     // Verify we received the broadcast
255                     waitTime = 0;
256                     while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
257                         try {
258                             receiver.wait(WAIT_TIME_INCR);
259                             waitTime += WAIT_TIME_INCR;
260                         } catch (InterruptedException e) {
261                             Log.i(TAG, "Interrupted during sleep", e);
262                         }
263                     }
264                     if (!receiver.isDone()) {
265                         fail("Timed out waiting for PACKAGE_ADDED notification");
266                     }
267                 }
268             }
269         } finally {
270             mContext.unregisterReceiver(receiver);
271         }
272     }
273 
invokeInstallPackageFail(Uri packageURI, int flags, int expectedResult)274     public void invokeInstallPackageFail(Uri packageURI, int flags, int expectedResult) {
275         TestInstallObserver observer = new TestInstallObserver();
276         try {
277             // Wait on observer
278             synchronized (observer) {
279                 getPm().installPackage(packageURI, observer, flags, null);
280                 long waitTime = 0;
281                 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
282                     try {
283                         observer.wait(WAIT_TIME_INCR);
284                         waitTime += WAIT_TIME_INCR;
285                     } catch (InterruptedException e) {
286                         Log.i(TAG, "Interrupted during sleep", e);
287                     }
288                 }
289                 if (!observer.isDone()) {
290                     fail("Timed out waiting for packageInstalled callback");
291                 }
292                 assertEquals(expectedResult, observer.returnCode);
293             }
294         } finally {
295         }
296     }
297 
getInstallablePackage(int fileResId, File outFile)298     Uri getInstallablePackage(int fileResId, File outFile) {
299         Resources res = mContext.getResources();
300         InputStream is = null;
301         try {
302             is = res.openRawResource(fileResId);
303         } catch (NotFoundException e) {
304             failStr("Failed to load resource with id: " + fileResId);
305         }
306         FileUtils.setPermissions(outFile.getPath(),
307                 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
308                 -1, -1);
309         assertTrue(FileUtils.copyToFile(is, outFile));
310         FileUtils.setPermissions(outFile.getPath(),
311                 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
312                 -1, -1);
313         return Uri.fromFile(outFile);
314     }
315 
parsePackage(Uri packageURI)316     private PackageParser.Package parsePackage(Uri packageURI) throws PackageParserException {
317         final String archiveFilePath = packageURI.getPath();
318         PackageParser packageParser = new PackageParser();
319         File sourceFile = new File(archiveFilePath);
320         PackageParser.Package pkg = packageParser.parseMonolithicPackage(sourceFile, 0);
321         packageParser = null;
322         return pkg;
323     }
324 
checkSd(long pkgLen)325     private boolean checkSd(long pkgLen) {
326         String status = Environment.getExternalStorageState();
327         if (!status.equals(Environment.MEDIA_MOUNTED)) {
328             return false;
329         }
330         long sdSize = -1;
331         StatFs sdStats = new StatFs(Environment.getExternalStorageDirectory().getPath());
332         sdSize = (long) sdStats.getAvailableBlocks() * (long) sdStats.getBlockSize();
333         // TODO check for thresholds here
334         return pkgLen <= sdSize;
335 
336     }
337 
checkInt(long pkgLen)338     private boolean checkInt(long pkgLen) {
339         StatFs intStats = new StatFs(Environment.getDataDirectory().getPath());
340         long intSize = (long) intStats.getBlockCount() * (long) intStats.getBlockSize();
341         long iSize = (long) intStats.getAvailableBlocks() * (long) intStats.getBlockSize();
342         // TODO check for thresholds here?
343         return pkgLen <= iSize;
344     }
345 
346     private static final int INSTALL_LOC_INT = 1;
347 
348     private static final int INSTALL_LOC_SD = 2;
349 
350     private static final int INSTALL_LOC_ERR = -1;
351 
getInstallLoc(int flags, int expInstallLocation, long pkgLen)352     private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) {
353         // Flags explicitly over ride everything else.
354         if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
355             return INSTALL_LOC_SD;
356         } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
357             return INSTALL_LOC_INT;
358         }
359         // Manifest option takes precedence next
360         if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
361             if (checkSd(pkgLen)) {
362                 return INSTALL_LOC_SD;
363             }
364             if (checkInt(pkgLen)) {
365                 return INSTALL_LOC_INT;
366             }
367             return INSTALL_LOC_ERR;
368         }
369         if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
370             if (checkInt(pkgLen)) {
371                 return INSTALL_LOC_INT;
372             }
373             return INSTALL_LOC_ERR;
374         }
375         if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
376             // Check for free memory internally
377             if (checkInt(pkgLen)) {
378                 return INSTALL_LOC_INT;
379             }
380             // Check for free memory externally
381             if (checkSd(pkgLen)) {
382                 return INSTALL_LOC_SD;
383             }
384             return INSTALL_LOC_ERR;
385         }
386         // Check for settings preference.
387         boolean checkSd = false;
388         int userPref = getDefaultInstallLoc();
389         if (userPref == APP_INSTALL_DEVICE) {
390             if (checkInt(pkgLen)) {
391                 return INSTALL_LOC_INT;
392             }
393             return INSTALL_LOC_ERR;
394         } else if (userPref == APP_INSTALL_SDCARD) {
395             if (checkSd(pkgLen)) {
396                 return INSTALL_LOC_SD;
397             }
398             return INSTALL_LOC_ERR;
399         }
400         // Default system policy for apps with no manifest option specified.
401         // Check for free memory internally
402         if (checkInt(pkgLen)) {
403             return INSTALL_LOC_INT;
404         }
405         return INSTALL_LOC_ERR;
406     }
407 
assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation)408     private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
409         try {
410             String pkgName = pkg.packageName;
411             ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
412             assertNotNull(info);
413             assertEquals(pkgName, info.packageName);
414             File dataDir = Environment.getDataDirectory();
415             String appInstallPath = new File(dataDir, "app").getPath();
416             String drmInstallPath = new File(dataDir, "app-private").getPath();
417             File srcDir = new File(info.sourceDir);
418             String srcPath = srcDir.getParentFile().getParent();
419             File publicSrcDir = new File(info.publicSourceDir);
420             String publicSrcPath = publicSrcDir.getParentFile().getParent();
421             long pkgLen = new File(info.sourceDir).length();
422             String expectedLibPath = new File(new File(info.sourceDir).getParentFile(), "lib")
423                     .getPath();
424 
425             int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
426             if (rLoc == INSTALL_LOC_INT) {
427                 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
428                     assertTrue("The application should be installed forward locked",
429                             (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
430                     assertStartsWith("The APK path should point to the ASEC",
431                             SECURE_CONTAINERS_PREFIX, srcPath);
432                     assertStartsWith("The public APK path should point to the ASEC",
433                             SECURE_CONTAINERS_PREFIX, publicSrcPath);
434                     assertStartsWith("The native library path should point to the ASEC",
435                             SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
436                 } else {
437                     assertFalse(
438                             (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
439                     assertEquals(appInstallPath, srcPath);
440                     assertEquals(appInstallPath, publicSrcPath);
441                     assertStartsWith("Native library should point to shared lib directory",
442                             expectedLibPath, info.nativeLibraryDir);
443                     assertDirOwnerGroupPermsIfExists(
444                             "Native library directory should be owned by system:system and 0755",
445                             Process.SYSTEM_UID, Process.SYSTEM_UID,
446                             S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH,
447                             info.nativeLibraryDir);
448                 }
449                 assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
450 
451                 // Make sure the native library dir is not a symlink
452                 final File nativeLibDir = new File(info.nativeLibraryDir);
453                 if (nativeLibDir.exists()) {
454                     try {
455                         assertEquals("Native library dir should not be a symlink",
456                                 info.nativeLibraryDir, nativeLibDir.getCanonicalPath());
457                     } catch (IOException e) {
458                         fail("Can't read " + nativeLibDir.getPath());
459                     }
460                 }
461             } else if (rLoc == INSTALL_LOC_SD) {
462                 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
463                     assertTrue("The application should be installed forward locked",
464                             (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
465                 } else {
466                     assertFalse("The application should not be installed forward locked",
467                             (info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0);
468                 }
469                 assertTrue("Application flags (" + info.flags
470                         + ") should contain FLAG_EXTERNAL_STORAGE",
471                         (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
472                 // Might need to check:
473                 // ((info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0)
474                 assertStartsWith("The APK path should point to the ASEC",
475                         SECURE_CONTAINERS_PREFIX, srcPath);
476                 assertStartsWith("The public APK path should point to the ASEC",
477                         SECURE_CONTAINERS_PREFIX, publicSrcPath);
478                 assertStartsWith("The native library path should point to the ASEC",
479                         SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
480 
481                 // Make sure the native library in /data/data/<app>/lib is a
482                 // symlink to the ASEC
483                 final File nativeLibSymLink = new File(info.dataDir, "lib");
484                 assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(),
485                         nativeLibSymLink.exists());
486                 try {
487                     assertEquals(nativeLibSymLink.getPath() + " should be a symlink to "
488                             + info.nativeLibraryDir, info.nativeLibraryDir,
489                             nativeLibSymLink.getCanonicalPath());
490                 } catch (IOException e) {
491                     fail("Can't read " + nativeLibSymLink.getPath());
492                 }
493             } else {
494                 // TODO handle error. Install should have failed.
495                 fail("Install should have failed");
496             }
497         } catch (NameNotFoundException e) {
498             failStr("failed with exception : " + e);
499         }
500     }
501 
assertDirOwnerGroupPermsIfExists(String reason, int uid, int gid, int perms, String path)502     private void assertDirOwnerGroupPermsIfExists(String reason, int uid, int gid, int perms,
503             String path) {
504         if (!new File(path).exists()) {
505             return;
506         }
507 
508         final StructStat stat;
509         try {
510             stat = Os.lstat(path);
511         } catch (ErrnoException e) {
512             throw new AssertionError(reason + "\n" + "Got: " + path + " does not exist");
513         }
514 
515         StringBuilder sb = new StringBuilder();
516 
517         if (!S_ISDIR(stat.st_mode)) {
518             sb.append("\nExpected type: ");
519             sb.append(S_IFDIR);
520             sb.append("\ngot type: ");
521             sb.append((stat.st_mode & S_IFMT));
522         }
523 
524         if (stat.st_uid != uid) {
525             sb.append("\nExpected owner: ");
526             sb.append(uid);
527             sb.append("\nGot owner: ");
528             sb.append(stat.st_uid);
529         }
530 
531         if (stat.st_gid != gid) {
532             sb.append("\nExpected group: ");
533             sb.append(gid);
534             sb.append("\nGot group: ");
535             sb.append(stat.st_gid);
536         }
537 
538         if ((stat.st_mode & ~S_IFMT) != perms) {
539             sb.append("\nExpected permissions: ");
540             sb.append(Integer.toOctalString(perms));
541             sb.append("\nGot permissions: ");
542             sb.append(Integer.toOctalString(stat.st_mode & ~S_IFMT));
543         }
544 
545         if (sb.length() > 0) {
546             throw new AssertionError(reason + sb.toString());
547         }
548     }
549 
assertStartsWith(String prefix, String actual)550     private static void assertStartsWith(String prefix, String actual) {
551         assertStartsWith("", prefix, actual);
552     }
553 
assertStartsWith(String description, String prefix, String actual)554     private static void assertStartsWith(String description, String prefix, String actual) {
555         if (!actual.startsWith(prefix)) {
556             StringBuilder sb = new StringBuilder(description);
557             sb.append("\nExpected prefix: ");
558             sb.append(prefix);
559             sb.append("\n     got: ");
560             sb.append(actual);
561             sb.append('\n');
562             throw new AssertionError(sb.toString());
563         }
564     }
565 
assertNotInstalled(String pkgName)566     private void assertNotInstalled(String pkgName) {
567         try {
568             ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
569             fail(pkgName + " shouldnt be installed");
570         } catch (NameNotFoundException e) {
571         }
572     }
573 
574     class InstallParams {
575         Uri packageURI;
576 
577         PackageParser.Package pkg;
578 
InstallParams(String outFileName, int rawResId)579         InstallParams(String outFileName, int rawResId) throws PackageParserException {
580             this.pkg = getParsedPackage(outFileName, rawResId);
581             this.packageURI = Uri.fromFile(new File(pkg.codePath));
582         }
583 
InstallParams(PackageParser.Package pkg)584         InstallParams(PackageParser.Package pkg) {
585             this.packageURI = Uri.fromFile(new File(pkg.codePath));
586             this.pkg = pkg;
587         }
588 
getApkSize()589         long getApkSize() {
590             File file = new File(pkg.codePath);
591             return file.length();
592         }
593     }
594 
sampleInstallFromRawResource(int flags, boolean cleanUp)595     private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) throws Exception {
596         return installFromRawResource("install.apk", R.raw.install, flags, cleanUp, false, -1,
597                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
598     }
599 
600     static final String PERM_PACKAGE = "package";
601 
602     static final String PERM_DEFINED = "defined";
603 
604     static final String PERM_UNDEFINED = "undefined";
605 
606     static final String PERM_USED = "used";
607 
608     static final String PERM_NOTUSED = "notused";
609 
assertPermissions(String[] cmds)610     private void assertPermissions(String[] cmds) {
611         final PackageManager pm = getPm();
612         String pkg = null;
613         PackageInfo pkgInfo = null;
614         String mode = PERM_DEFINED;
615         int i = 0;
616         while (i < cmds.length) {
617             String cmd = cmds[i++];
618             if (cmd == PERM_PACKAGE) {
619                 pkg = cmds[i++];
620                 try {
621                     pkgInfo = pm.getPackageInfo(pkg,
622                             PackageManager.GET_PERMISSIONS
623                             | PackageManager.GET_UNINSTALLED_PACKAGES);
624                 } catch (NameNotFoundException e) {
625                     pkgInfo = null;
626                 }
627             } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED
628                     || cmd == PERM_USED || cmd == PERM_NOTUSED) {
629                 mode = cmds[i++];
630             } else {
631                 if (mode == PERM_DEFINED) {
632                     try {
633                         PermissionInfo pi = pm.getPermissionInfo(cmd, 0);
634                         assertNotNull(pi);
635                         assertEquals(pi.packageName, pkg);
636                         assertEquals(pi.name, cmd);
637                         assertNotNull(pkgInfo);
638                         boolean found = false;
639                         for (int j = 0; j < pkgInfo.permissions.length && !found; j++) {
640                             if (pkgInfo.permissions[j].name.equals(cmd)) {
641                                 found = true;
642                             }
643                         }
644                         if (!found) {
645                             fail("Permission not found: " + cmd);
646                         }
647                     } catch (NameNotFoundException e) {
648                         throw new RuntimeException(e);
649                     }
650                 } else if (mode == PERM_UNDEFINED) {
651                     try {
652                         pm.getPermissionInfo(cmd, 0);
653                         throw new RuntimeException("Permission exists: " + cmd);
654                     } catch (NameNotFoundException e) {
655                     }
656                     if (pkgInfo != null) {
657                         boolean found = false;
658                         for (int j = 0; j < pkgInfo.permissions.length && !found; j++) {
659                             if (pkgInfo.permissions[j].name.equals(cmd)) {
660                                 found = true;
661                             }
662                         }
663                         if (found) {
664                             fail("Permission still exists: " + cmd);
665                         }
666                     }
667                 } else if (mode == PERM_USED || mode == PERM_NOTUSED) {
668                     boolean found = false;
669                     for (int j = 0; j < pkgInfo.requestedPermissions.length && !found; j++) {
670                         if (pkgInfo.requestedPermissions[j].equals(cmd)) {
671                             found = true;
672                         }
673                     }
674                     if (!found) {
675                         fail("Permission not requested: " + cmd);
676                     }
677                     if (mode == PERM_USED) {
678                         if (pm.checkPermission(cmd, pkg) != PackageManager.PERMISSION_GRANTED) {
679                             fail("Permission not granted: " + cmd);
680                         }
681                     } else {
682                         if (pm.checkPermission(cmd, pkg) != PackageManager.PERMISSION_DENIED) {
683                             fail("Permission granted: " + cmd);
684                         }
685                     }
686                 }
687             }
688         }
689     }
690 
getParsedPackage(String outFileName, int rawResId)691     private PackageParser.Package getParsedPackage(String outFileName, int rawResId)
692             throws PackageParserException {
693         PackageManager pm = mContext.getPackageManager();
694         File filesDir = mContext.getFilesDir();
695         File outFile = new File(filesDir, outFileName);
696         Uri packageURI = getInstallablePackage(rawResId, outFile);
697         PackageParser.Package pkg = parsePackage(packageURI);
698         return pkg;
699     }
700 
701     /*
702      * Utility function that reads a apk bundled as a raw resource
703      * copies it into own data directory and invokes
704      * PackageManager api to install it.
705      */
installFromRawResource(InstallParams ip, int flags, boolean cleanUp, boolean fail, int result, int expInstallLocation)706     private void installFromRawResource(InstallParams ip, int flags, boolean cleanUp, boolean fail,
707             int result, int expInstallLocation) throws Exception {
708         PackageManager pm = mContext.getPackageManager();
709         PackageParser.Package pkg = ip.pkg;
710         Uri packageURI = ip.packageURI;
711         if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
712             // Make sure the package doesn't exist
713             try {
714                 ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName,
715                         PackageManager.GET_UNINSTALLED_PACKAGES);
716                 GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
717                 invokeDeletePackage(pkg.packageName, 0, receiver);
718             } catch (NameNotFoundException e) {
719             }
720         }
721         try {
722             if (fail) {
723                 invokeInstallPackageFail(packageURI, flags, result);
724                 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
725                     assertNotInstalled(pkg.packageName);
726                 }
727             } else {
728                 InstallReceiver receiver = new InstallReceiver(pkg.packageName);
729                 invokeInstallPackage(packageURI, flags, receiver, true);
730                 // Verify installed information
731                 assertInstall(pkg, flags, expInstallLocation);
732             }
733         } finally {
734             if (cleanUp) {
735                 cleanUpInstall(ip);
736             }
737         }
738     }
739 
740     /*
741      * Utility function that reads a apk bundled as a raw resource
742      * copies it into own data directory and invokes
743      * PackageManager api to install it.
744      */
installFromRawResource(String outFileName, int rawResId, int flags, boolean cleanUp, boolean fail, int result, int expInstallLocation)745     private InstallParams installFromRawResource(String outFileName, int rawResId, int flags,
746             boolean cleanUp, boolean fail, int result, int expInstallLocation) throws Exception {
747         InstallParams ip = new InstallParams(outFileName, rawResId);
748         installFromRawResource(ip, flags, cleanUp, fail, result, expInstallLocation);
749         return ip;
750     }
751 
752     @LargeTest
testInstallNormalInternal()753     public void testInstallNormalInternal() throws Exception {
754         sampleInstallFromRawResource(0, true);
755     }
756 
757     @LargeTest
testInstallFwdLockedInternal()758     public void testInstallFwdLockedInternal() throws Exception {
759         sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
760     }
761 
762     @LargeTest
testInstallSdcard()763     public void testInstallSdcard() throws Exception {
764         // Do not run on devices with emulated external storage.
765         if (Environment.isExternalStorageEmulated()) {
766             return;
767         }
768 
769         mountMedia();
770         sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
771     }
772 
773     /* ------------------------- Test replacing packages -------------- */
774     class ReplaceReceiver extends GenericReceiver {
775         String pkgName;
776 
777         final static int INVALID = -1;
778 
779         final static int REMOVED = 1;
780 
781         final static int ADDED = 2;
782 
783         final static int REPLACED = 3;
784 
785         int removed = INVALID;
786 
787         // for updated system apps only
788         boolean update = false;
789 
ReplaceReceiver(String pkgName)790         ReplaceReceiver(String pkgName) {
791             this.pkgName = pkgName;
792             filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
793             filter.addAction(Intent.ACTION_PACKAGE_ADDED);
794             if (update) {
795                 filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
796             }
797             filter.addDataScheme("package");
798             super.setFilter(filter);
799         }
800 
notifyNow(Intent intent)801         public boolean notifyNow(Intent intent) {
802             String action = intent.getAction();
803             Uri data = intent.getData();
804             String installedPkg = data.getEncodedSchemeSpecificPart();
805             if (pkgName == null || !pkgName.equals(installedPkg)) {
806                 return false;
807             }
808             if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
809                 removed = REMOVED;
810             } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
811                 if (removed != REMOVED) {
812                     return false;
813                 }
814                 boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
815                 if (!replacing) {
816                     return false;
817                 }
818                 removed = ADDED;
819                 if (!update) {
820                     return true;
821                 }
822             } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
823                 if (removed != ADDED) {
824                     return false;
825                 }
826                 removed = REPLACED;
827                 return true;
828             }
829             return false;
830         }
831     }
832 
833     /*
834      * Utility function that reads a apk bundled as a raw resource
835      * copies it into own data directory and invokes
836      * PackageManager api to install first and then replace it
837      * again.
838      */
sampleReplaceFromRawResource(int flags)839     private void sampleReplaceFromRawResource(int flags) throws Exception {
840         InstallParams ip = sampleInstallFromRawResource(flags, false);
841         boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
842         Log.i(TAG, "replace=" + replace);
843         GenericReceiver receiver;
844         if (replace) {
845             receiver = new ReplaceReceiver(ip.pkg.packageName);
846             Log.i(TAG, "Creating replaceReceiver");
847         } else {
848             receiver = new InstallReceiver(ip.pkg.packageName);
849         }
850         try {
851             invokeInstallPackage(ip.packageURI, flags, receiver, replace);
852             if (replace) {
853                 assertInstall(ip.pkg, flags, ip.pkg.installLocation);
854             }
855         } finally {
856             cleanUpInstall(ip);
857         }
858     }
859 
860     @LargeTest
testReplaceFailNormalInternal()861     public void testReplaceFailNormalInternal() throws Exception {
862         sampleReplaceFromRawResource(0);
863     }
864 
865     @LargeTest
testReplaceFailFwdLockedInternal()866     public void testReplaceFailFwdLockedInternal() throws Exception {
867         sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
868     }
869 
870     @LargeTest
testReplaceFailSdcard()871     public void testReplaceFailSdcard() throws Exception {
872         // Do not run on devices with emulated external storage.
873         if (Environment.isExternalStorageEmulated()) {
874             return;
875         }
876 
877         sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
878     }
879 
880     @LargeTest
testReplaceNormalInternal()881     public void testReplaceNormalInternal() throws Exception {
882         sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
883     }
884 
885     @LargeTest
testReplaceFwdLockedInternal()886     public void testReplaceFwdLockedInternal() throws Exception {
887         sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING
888                 | PackageManager.INSTALL_FORWARD_LOCK);
889     }
890 
891     @LargeTest
testReplaceSdcard()892     public void testReplaceSdcard() throws Exception {
893         // Do not run on devices with emulated external storage.
894         if (Environment.isExternalStorageEmulated()) {
895             return;
896         }
897 
898         sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING
899                 | PackageManager.INSTALL_EXTERNAL);
900     }
901 
902     /* -------------- Delete tests --- */
903     private static class DeleteObserver extends IPackageDeleteObserver.Stub {
904         private CountDownLatch mLatch = new CountDownLatch(1);
905 
906         private int mReturnCode;
907 
908         private final String mPackageName;
909 
910         private String mObservedPackage;
911 
DeleteObserver(String packageName)912         public DeleteObserver(String packageName) {
913             mPackageName = packageName;
914         }
915 
isSuccessful()916         public boolean isSuccessful() {
917             return mReturnCode == PackageManager.DELETE_SUCCEEDED;
918         }
919 
packageDeleted(String packageName, int returnCode)920         public void packageDeleted(String packageName, int returnCode) throws RemoteException {
921             mObservedPackage = packageName;
922 
923             mReturnCode = returnCode;
924 
925             mLatch.countDown();
926         }
927 
waitForCompletion(long timeoutMillis)928         public void waitForCompletion(long timeoutMillis) {
929             final long deadline = SystemClock.uptimeMillis() + timeoutMillis;
930 
931             long waitTime = timeoutMillis;
932             while (waitTime > 0) {
933                 try {
934                     boolean done = mLatch.await(waitTime, TimeUnit.MILLISECONDS);
935                     if (done) {
936                         assertEquals(mPackageName, mObservedPackage);
937                         return;
938                     }
939                 } catch (InterruptedException e) {
940                     // TODO Auto-generated catch block
941                     e.printStackTrace();
942                 }
943                 waitTime = deadline - SystemClock.uptimeMillis();
944             }
945 
946             throw new AssertionError("Timeout waiting for package deletion");
947         }
948     }
949 
950     class DeleteReceiver extends GenericReceiver {
951         String pkgName;
952 
DeleteReceiver(String pkgName)953         DeleteReceiver(String pkgName) {
954             this.pkgName = pkgName;
955             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
956             filter.addDataScheme("package");
957             super.setFilter(filter);
958         }
959 
notifyNow(Intent intent)960         public boolean notifyNow(Intent intent) {
961             String action = intent.getAction();
962             if (!Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
963                 return false;
964             }
965             Uri data = intent.getData();
966             String installedPkg = data.getEncodedSchemeSpecificPart();
967             if (pkgName.equals(installedPkg)) {
968                 return true;
969             }
970             return false;
971         }
972     }
973 
invokeDeletePackage(final String pkgName, int flags, GenericReceiver receiver)974     public boolean invokeDeletePackage(final String pkgName, int flags, GenericReceiver receiver)
975             throws Exception {
976         ApplicationInfo info = getPm().getApplicationInfo(pkgName,
977                 PackageManager.GET_UNINSTALLED_PACKAGES);
978 
979         mContext.registerReceiver(receiver, receiver.filter);
980         try {
981             DeleteObserver observer = new DeleteObserver(pkgName);
982 
983             getPm().deletePackage(pkgName, observer, flags | PackageManager.DELETE_ALL_USERS);
984             observer.waitForCompletion(MAX_WAIT_TIME);
985 
986             assertUninstalled(info);
987 
988             // Verify we received the broadcast
989             // TODO replace this with a CountDownLatch
990             synchronized (receiver) {
991                 long waitTime = 0;
992                 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
993                     receiver.wait(WAIT_TIME_INCR);
994                     waitTime += WAIT_TIME_INCR;
995                 }
996                 if (!receiver.isDone()) {
997                     throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
998                 }
999             }
1000             return receiver.received;
1001         } finally {
1002             mContext.unregisterReceiver(receiver);
1003         }
1004     }
1005 
assertUninstalled(ApplicationInfo info)1006     private static void assertUninstalled(ApplicationInfo info) throws Exception {
1007         File nativeLibraryFile = new File(info.nativeLibraryDir);
1008         assertFalse("Native library directory " + info.nativeLibraryDir
1009                 + " should be erased", nativeLibraryFile.exists());
1010     }
1011 
deleteFromRawResource(int iFlags, int dFlags)1012     public void deleteFromRawResource(int iFlags, int dFlags) throws Exception {
1013         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1014         boolean retainData = ((dFlags & PackageManager.DELETE_KEEP_DATA) != 0);
1015         GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1016         try {
1017             assertTrue(invokeDeletePackage(ip.pkg.packageName, dFlags, receiver));
1018             ApplicationInfo info = null;
1019             Log.i(TAG, "okay4");
1020             try {
1021                 info = getPm().getApplicationInfo(ip.pkg.packageName,
1022                         PackageManager.GET_UNINSTALLED_PACKAGES);
1023             } catch (NameNotFoundException e) {
1024                 info = null;
1025             }
1026             if (retainData) {
1027                 assertNotNull(info);
1028                 assertEquals(info.packageName, ip.pkg.packageName);
1029                 File file = new File(info.dataDir);
1030                 assertTrue(file.exists());
1031             } else {
1032                 assertNull(info);
1033             }
1034         } catch (Exception e) {
1035             failStr(e);
1036         } finally {
1037             cleanUpInstall(ip);
1038         }
1039     }
1040 
1041     @LargeTest
testDeleteNormalInternal()1042     public void testDeleteNormalInternal() throws Exception {
1043         deleteFromRawResource(0, 0);
1044     }
1045 
1046     @LargeTest
testDeleteFwdLockedInternal()1047     public void testDeleteFwdLockedInternal() throws Exception {
1048         deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0);
1049     }
1050 
1051     @LargeTest
testDeleteSdcard()1052     public void testDeleteSdcard() throws Exception {
1053         // Do not run on devices with emulated external storage.
1054         if (Environment.isExternalStorageEmulated()) {
1055             return;
1056         }
1057 
1058         deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
1059     }
1060 
1061     @LargeTest
testDeleteNormalInternalRetainData()1062     public void testDeleteNormalInternalRetainData() throws Exception {
1063         deleteFromRawResource(0, PackageManager.DELETE_KEEP_DATA);
1064     }
1065 
1066     @LargeTest
testDeleteFwdLockedInternalRetainData()1067     public void testDeleteFwdLockedInternalRetainData() throws Exception {
1068         deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DELETE_KEEP_DATA);
1069     }
1070 
1071     @LargeTest
testDeleteSdcardRetainData()1072     public void testDeleteSdcardRetainData() throws Exception {
1073         // Do not run on devices with emulated external storage.
1074         if (Environment.isExternalStorageEmulated()) {
1075             return;
1076         }
1077 
1078         deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DELETE_KEEP_DATA);
1079     }
1080 
1081     /* sdcard mount/unmount tests ***** */
1082 
1083     class SdMountReceiver extends GenericReceiver {
1084         String pkgNames[];
1085 
1086         boolean status = true;
1087 
SdMountReceiver(String[] pkgNames)1088         SdMountReceiver(String[] pkgNames) {
1089             this.pkgNames = pkgNames;
1090             IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1091             super.setFilter(filter);
1092         }
1093 
notifyNow(Intent intent)1094         public boolean notifyNow(Intent intent) {
1095             Log.i(TAG, "okay 1");
1096             String action = intent.getAction();
1097             if (!Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1098                 return false;
1099             }
1100             String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1101             for (String pkg : pkgNames) {
1102                 boolean found = false;
1103                 for (String rpkg : rpkgList) {
1104                     if (rpkg.equals(pkg)) {
1105                         found = true;
1106                         break;
1107                     }
1108                 }
1109                 if (!found) {
1110                     status = false;
1111                     return true;
1112                 }
1113             }
1114             return true;
1115         }
1116     }
1117 
1118     class SdUnMountReceiver extends GenericReceiver {
1119         String pkgNames[];
1120 
1121         boolean status = true;
1122 
SdUnMountReceiver(String[] pkgNames)1123         SdUnMountReceiver(String[] pkgNames) {
1124             this.pkgNames = pkgNames;
1125             IntentFilter filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1126             super.setFilter(filter);
1127         }
1128 
notifyNow(Intent intent)1129         public boolean notifyNow(Intent intent) {
1130             String action = intent.getAction();
1131             if (!Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1132                 return false;
1133             }
1134             String rpkgList[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1135             for (String pkg : pkgNames) {
1136                 boolean found = false;
1137                 for (String rpkg : rpkgList) {
1138                     if (rpkg.equals(pkg)) {
1139                         found = true;
1140                         break;
1141                     }
1142                 }
1143                 if (!found) {
1144                     status = false;
1145                     return true;
1146                 }
1147             }
1148             return true;
1149         }
1150     }
1151 
getMs()1152     IMountService getMs() {
1153         IBinder service = ServiceManager.getService("mount");
1154         if (service != null) {
1155             return IMountService.Stub.asInterface(service);
1156         } else {
1157             Log.e(TAG, "Can't get mount service");
1158         }
1159         return null;
1160     }
1161 
checkMediaState(String desired)1162     boolean checkMediaState(String desired) {
1163         String actual = Environment.getExternalStorageState();
1164         if (desired.equals(actual)) {
1165             return true;
1166         } else {
1167             return false;
1168         }
1169     }
1170 
mountMedia()1171     boolean mountMedia() {
1172         // We can't mount emulated storage.
1173         if (Environment.isExternalStorageEmulated()) {
1174             return true;
1175         }
1176 
1177         if (checkMediaState(Environment.MEDIA_MOUNTED)) {
1178             return true;
1179         }
1180 
1181         final String path = Environment.getExternalStorageDirectory().toString();
1182         StorageListener observer = new StorageListener(Environment.MEDIA_MOUNTED);
1183         StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
1184         sm.registerListener(observer);
1185         try {
1186             // Wait on observer
1187             synchronized (observer) {
1188                 int ret = getMs().mountVolume(path);
1189                 if (ret != StorageResultCode.OperationSucceeded) {
1190                     throw new Exception("Could not mount the media");
1191                 }
1192                 long waitTime = 0;
1193                 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1194                     observer.wait(WAIT_TIME_INCR);
1195                     waitTime += WAIT_TIME_INCR;
1196                 }
1197                 if (!observer.isDone()) {
1198                     throw new Exception("Timed out waiting for unmount media notification");
1199                 }
1200                 return true;
1201             }
1202         } catch (Exception e) {
1203             Log.e(TAG, "Exception : " + e);
1204             return false;
1205         } finally {
1206             sm.unregisterListener(observer);
1207         }
1208     }
1209 
unmountMedia()1210     private boolean unmountMedia() {
1211         // We can't unmount emulated storage.
1212         if (Environment.isExternalStorageEmulated()) {
1213             return true;
1214         }
1215 
1216         if (checkMediaState(Environment.MEDIA_UNMOUNTED)) {
1217             return true;
1218         }
1219 
1220         final String path = Environment.getExternalStorageDirectory().getPath();
1221         StorageListener observer = new StorageListener(Environment.MEDIA_UNMOUNTED);
1222         StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
1223         sm.registerListener(observer);
1224         try {
1225             // Wait on observer
1226             synchronized (observer) {
1227                 getMs().unmountVolume(path, true, false);
1228                 long waitTime = 0;
1229                 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1230                     observer.wait(WAIT_TIME_INCR);
1231                     waitTime += WAIT_TIME_INCR;
1232                 }
1233                 if (!observer.isDone()) {
1234                     throw new Exception("Timed out waiting for unmount media notification");
1235                 }
1236                 return true;
1237             }
1238         } catch (Exception e) {
1239             Log.e(TAG, "Exception : " + e);
1240             return false;
1241         } finally {
1242             sm.unregisterListener(observer);
1243         }
1244     }
1245 
mountFromRawResource()1246     private boolean mountFromRawResource() throws Exception {
1247         // Install pkg on sdcard
1248         InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false);
1249         if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
1250         boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1251         boolean registeredReceiver = false;
1252         SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName});
1253         try {
1254             if (localLOGV) Log.i(TAG, "Unmounting media");
1255             // Unmount media
1256             assertTrue(unmountMedia());
1257             if (localLOGV) Log.i(TAG, "Unmounted media");
1258             // Register receiver here
1259             PackageManager pm = getPm();
1260             mContext.registerReceiver(receiver, receiver.filter);
1261             registeredReceiver = true;
1262 
1263             // Wait on receiver
1264             synchronized (receiver) {
1265                 if (localLOGV) Log.i(TAG, "Mounting media");
1266                 // Mount media again
1267                 assertTrue(mountMedia());
1268                 if (localLOGV) Log.i(TAG, "Mounted media");
1269                 if (localLOGV) Log.i(TAG, "Waiting for notification");
1270                 long waitTime = 0;
1271                 // Verify we received the broadcast
1272                 waitTime = 0;
1273                 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
1274                     receiver.wait(WAIT_TIME_INCR);
1275                     waitTime += WAIT_TIME_INCR;
1276                 }
1277                 if(!receiver.isDone()) {
1278                     failStr("Timed out waiting for EXTERNAL_APPLICATIONS notification");
1279                 }
1280                 return receiver.received;
1281             }
1282         } catch (InterruptedException e) {
1283             failStr(e);
1284             return false;
1285         } finally {
1286             if (registeredReceiver) {
1287                 mContext.unregisterReceiver(receiver);
1288             }
1289             // Restore original media state
1290             if (origState) {
1291                 mountMedia();
1292             } else {
1293                 unmountMedia();
1294             }
1295             if (localLOGV) Log.i(TAG, "Cleaning up install");
1296             cleanUpInstall(ip);
1297         }
1298     }
1299 
1300     /*
1301      * Install package on sdcard. Unmount and then mount the media.
1302      * (Use PackageManagerService private api for now)
1303      * Make sure the installed package is available.
1304      */
1305     @LargeTest
testMountSdNormalInternal()1306     public void testMountSdNormalInternal() throws Exception {
1307         // Do not run on devices with emulated external storage.
1308         if (Environment.isExternalStorageEmulated()) {
1309             return;
1310         }
1311 
1312         assertTrue(mountFromRawResource());
1313     }
1314 
cleanUpInstall(InstallParams ip)1315     void cleanUpInstall(InstallParams ip) throws Exception {
1316         if (ip == null) {
1317             return;
1318         }
1319         Runtime.getRuntime().gc();
1320 
1321         final String packageName = ip.pkg.packageName;
1322         Log.i(TAG, "Deleting package : " + packageName);
1323 
1324         ApplicationInfo info = null;
1325         try {
1326             info = getPm().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
1327         } catch (NameNotFoundException ignored) {
1328         }
1329 
1330         DeleteObserver observer = new DeleteObserver(packageName);
1331         getPm().deletePackage(packageName, observer, PackageManager.DELETE_ALL_USERS);
1332         observer.waitForCompletion(MAX_WAIT_TIME);
1333 
1334         try {
1335             if (info != null) {
1336                 assertUninstalled(info);
1337             }
1338         } finally {
1339             File outFile = new File(ip.pkg.codePath);
1340             if (outFile != null && outFile.exists()) {
1341                 outFile.delete();
1342             }
1343         }
1344     }
1345 
cleanUpInstall(String pkgName)1346     private void cleanUpInstall(String pkgName) throws Exception {
1347         if (pkgName == null) {
1348             return;
1349         }
1350         Log.i(TAG, "Deleting package : " + pkgName);
1351         try {
1352             ApplicationInfo info = getPm().getApplicationInfo(pkgName,
1353                     PackageManager.GET_UNINSTALLED_PACKAGES);
1354 
1355             if (info != null) {
1356                 DeleteObserver observer = new DeleteObserver(pkgName);
1357                 getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS);
1358                 observer.waitForCompletion(MAX_WAIT_TIME);
1359                 assertUninstalled(info);
1360             }
1361         } catch (NameNotFoundException e) {
1362         }
1363     }
1364 
1365     @LargeTest
testManifestInstallLocationInternal()1366     public void testManifestInstallLocationInternal() throws Exception {
1367         installFromRawResource("install.apk", R.raw.install_loc_internal,
1368                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1369     }
1370 
1371     @LargeTest
testManifestInstallLocationSdcard()1372     public void testManifestInstallLocationSdcard() throws Exception {
1373         // Do not run on devices with emulated external storage.
1374         if (Environment.isExternalStorageEmulated()) {
1375             return;
1376         }
1377 
1378         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1379                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1380     }
1381 
1382     @LargeTest
testManifestInstallLocationAuto()1383     public void testManifestInstallLocationAuto() throws Exception {
1384         installFromRawResource("install.apk", R.raw.install_loc_auto,
1385                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
1386     }
1387 
1388     @LargeTest
testManifestInstallLocationUnspecified()1389     public void testManifestInstallLocationUnspecified() throws Exception {
1390         installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1391                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1392     }
1393 
1394     @LargeTest
testManifestInstallLocationFwdLockedFlagSdcard()1395     public void testManifestInstallLocationFwdLockedFlagSdcard() throws Exception {
1396         // Do not run on devices with emulated external storage.
1397         if (Environment.isExternalStorageEmulated()) {
1398             return;
1399         }
1400 
1401         installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1402                 PackageManager.INSTALL_FORWARD_LOCK |
1403                 PackageManager.INSTALL_EXTERNAL, true, false, -1,
1404                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1405     }
1406 
1407     @LargeTest
testManifestInstallLocationFwdLockedSdcard()1408     public void testManifestInstallLocationFwdLockedSdcard() throws Exception {
1409         // Do not run on devices with emulated external storage.
1410         if (Environment.isExternalStorageEmulated()) {
1411             return;
1412         }
1413 
1414         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1415                 PackageManager.INSTALL_FORWARD_LOCK, true, false, -1,
1416                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1417     }
1418 
1419     /*
1420      * Install a package on internal flash via PackageManager install flag. Replace
1421      * the package via flag to install on sdcard. Make sure the new flag overrides
1422      * the old install location.
1423      */
1424     @LargeTest
testReplaceFlagInternalSdcard()1425     public void testReplaceFlagInternalSdcard() throws Exception {
1426         // Do not run on devices with emulated external storage.
1427         if (Environment.isExternalStorageEmulated()) {
1428             return;
1429         }
1430 
1431         int iFlags = 0;
1432         int rFlags = PackageManager.INSTALL_EXTERNAL;
1433         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1434         GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1435         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1436         try {
1437             invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1438             assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
1439         } catch (Exception e) {
1440             failStr("Failed with exception : " + e);
1441         } finally {
1442             cleanUpInstall(ip);
1443         }
1444     }
1445 
1446     /*
1447      * Install a package on sdcard via PackageManager install flag. Replace
1448      * the package with no flags or manifest option and make sure the old
1449      * install location is retained.
1450      */
1451     @LargeTest
testReplaceFlagSdcardInternal()1452     public void testReplaceFlagSdcardInternal() throws Exception {
1453         // Do not run on devices with emulated external storage.
1454         if (Environment.isExternalStorageEmulated()) {
1455             return;
1456         }
1457 
1458         int iFlags = PackageManager.INSTALL_EXTERNAL;
1459         int rFlags = 0;
1460         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
1461         GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1462         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1463         try {
1464             invokeInstallPackage(ip.packageURI, replaceFlags, receiver, true);
1465             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1466         } catch (Exception e) {
1467             failStr("Failed with exception : " + e);
1468         } finally {
1469             cleanUpInstall(ip);
1470         }
1471     }
1472 
1473     @LargeTest
testManifestInstallLocationReplaceInternalSdcard()1474     public void testManifestInstallLocationReplaceInternalSdcard() throws Exception {
1475         // Do not run on devices with emulated external storage.
1476         if (Environment.isExternalStorageEmulated()) {
1477             return;
1478         }
1479 
1480         int iFlags = 0;
1481         int iApk = R.raw.install_loc_internal;
1482         int rFlags = 0;
1483         int rApk = R.raw.install_loc_sdcard;
1484         InstallParams ip = installFromRawResource("install.apk", iApk,
1485                 iFlags, false,
1486                 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1487         GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1488         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1489         try {
1490             InstallParams rp = installFromRawResource("install.apk", rApk,
1491                     replaceFlags, false,
1492                     false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1493             assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
1494         } catch (Exception e) {
1495             failStr("Failed with exception : " + e);
1496         } finally {
1497             cleanUpInstall(ip);
1498         }
1499     }
1500 
1501     @LargeTest
testManifestInstallLocationReplaceSdcardInternal()1502     public void testManifestInstallLocationReplaceSdcardInternal() throws Exception {
1503         // Do not run on devices with emulated external storage.
1504         if (Environment.isExternalStorageEmulated()) {
1505             return;
1506         }
1507 
1508         int iFlags = 0;
1509         int iApk = R.raw.install_loc_sdcard;
1510         int rFlags = 0;
1511         int rApk = R.raw.install_loc_unspecified;
1512         InstallParams ip = installFromRawResource("install.apk", iApk,
1513                 iFlags, false,
1514                 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1515         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1516         try {
1517             InstallParams rp = installFromRawResource("install.apk", rApk,
1518                     replaceFlags, false,
1519                     false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1520             assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
1521         } catch (Exception e) {
1522             failStr("Failed with exception : " + e);
1523         } finally {
1524             cleanUpInstall(ip);
1525         }
1526     }
1527 
1528     class MoveReceiver extends GenericReceiver {
1529         String pkgName;
1530 
1531         final static int INVALID = -1;
1532 
1533         final static int REMOVED = 1;
1534 
1535         final static int ADDED = 2;
1536 
1537         int removed = INVALID;
1538 
MoveReceiver(String pkgName)1539         MoveReceiver(String pkgName) {
1540             this.pkgName = pkgName;
1541             filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1542             filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1543             super.setFilter(filter);
1544         }
1545 
notifyNow(Intent intent)1546         public boolean notifyNow(Intent intent) {
1547             String action = intent.getAction();
1548             Log.i(TAG, "MoveReceiver::" + action);
1549             if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1550                 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1551                 if (list != null) {
1552                     for (String pkg : list) {
1553                         if (pkg.equals(pkgName)) {
1554                             removed = REMOVED;
1555                             break;
1556                         }
1557                     }
1558                 }
1559                 removed = REMOVED;
1560             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1561                 if (removed != REMOVED) {
1562                     return false;
1563                 }
1564                 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1565                 if (list != null) {
1566                     for (String pkg : list) {
1567                         if (pkg.equals(pkgName)) {
1568                             removed = ADDED;
1569                             return true;
1570                         }
1571                     }
1572                 }
1573             }
1574             return false;
1575         }
1576     }
1577 
invokeMovePackage(String pkgName, int flags, GenericReceiver receiver)1578     public boolean invokeMovePackage(String pkgName, int flags, GenericReceiver receiver)
1579             throws Exception {
1580         throw new UnsupportedOperationException();
1581     }
1582 
invokeMovePackageFail(String pkgName, int flags, int errCode)1583     private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception {
1584         throw new UnsupportedOperationException();
1585     }
1586 
getDefaultInstallLoc()1587     private int getDefaultInstallLoc() {
1588         int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
1589         try {
1590             origDefaultLoc = Settings.Global.getInt(mContext.getContentResolver(),
1591                     Settings.Global.DEFAULT_INSTALL_LOCATION);
1592         } catch (SettingNotFoundException e1) {
1593         }
1594         return origDefaultLoc;
1595     }
1596 
setInstallLoc(int loc)1597     private void setInstallLoc(int loc) {
1598         Settings.Global.putInt(mContext.getContentResolver(),
1599                 Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
1600     }
1601 
1602     /*
1603      * Tests for moving apps between internal and external storage
1604      */
1605     /*
1606      * Utility function that reads a apk bundled as a raw resource
1607      * copies it into own data directory and invokes
1608      * PackageManager api to install first and then replace it
1609      * again.
1610      */
1611 
moveFromRawResource(String outFileName, int rawResId, int installFlags, int moveFlags, boolean cleanUp, boolean fail, int result)1612     private void moveFromRawResource(String outFileName, int rawResId, int installFlags,
1613             int moveFlags, boolean cleanUp, boolean fail, int result) throws Exception {
1614         int origDefaultLoc = getDefaultInstallLoc();
1615         InstallParams ip = null;
1616         try {
1617             setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1618             // Install first
1619             ip = installFromRawResource("install.apk", rawResId, installFlags, false,
1620                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1621             ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1622             if (fail) {
1623                 assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1624                 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1625                 assertNotNull(info);
1626                 assertEquals(oldAppInfo.flags, info.flags);
1627             } else {
1628                 // Create receiver based on expRetCode
1629                 MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
1630                 boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, receiver);
1631                 assertTrue(retCode);
1632                 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1633                 assertNotNull("ApplicationInfo for recently installed application should exist",
1634                         info);
1635                 if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
1636                     assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set",
1637                             (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
1638                     assertStartsWith("Native library dir should be in dataDir",
1639                             info.dataDir, info.nativeLibraryDir);
1640                 } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0) {
1641                     assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set",
1642                             (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
1643                     assertStartsWith("Native library dir should point to ASEC",
1644                             SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
1645                 }
1646             }
1647         } catch (NameNotFoundException e) {
1648             failStr("Pkg hasnt been installed correctly");
1649         } finally {
1650             if (ip != null) {
1651                 cleanUpInstall(ip);
1652             }
1653             // Restore default install location
1654             setInstallLoc(origDefaultLoc);
1655         }
1656     }
1657 
sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail, int result)1658     private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail,
1659             int result) throws Exception {
1660         moveFromRawResource("install.apk",
1661                 R.raw.install, installFlags, moveFlags, true,
1662                 fail, result);
1663     }
1664 
1665     @LargeTest
testMoveAppInternalToExternal()1666     public void testMoveAppInternalToExternal() throws Exception {
1667         // Do not run on devices with emulated external storage.
1668         if (Environment.isExternalStorageEmulated()) {
1669             return;
1670         }
1671 
1672         int installFlags = PackageManager.INSTALL_INTERNAL;
1673         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1674         boolean fail = false;
1675         int result = PackageManager.MOVE_SUCCEEDED;
1676         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1677     }
1678 
1679     @Suppress
1680     @LargeTest
testMoveAppInternalToInternal()1681     public void testMoveAppInternalToInternal() throws Exception {
1682         int installFlags = PackageManager.INSTALL_INTERNAL;
1683         int moveFlags = PackageManager.MOVE_INTERNAL;
1684         boolean fail = true;
1685         int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1686         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1687     }
1688 
1689     @LargeTest
testMoveAppExternalToExternal()1690     public void testMoveAppExternalToExternal() throws Exception {
1691         // Do not run on devices with emulated external storage.
1692         if (Environment.isExternalStorageEmulated()) {
1693             return;
1694         }
1695 
1696         int installFlags = PackageManager.INSTALL_EXTERNAL;
1697         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1698         boolean fail = true;
1699         int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1700         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1701     }
1702 
1703     @LargeTest
testMoveAppExternalToInternal()1704     public void testMoveAppExternalToInternal() throws Exception {
1705         // Do not run on devices with emulated external storage.
1706         if (Environment.isExternalStorageEmulated()) {
1707             return;
1708         }
1709 
1710         int installFlags = PackageManager.INSTALL_EXTERNAL;
1711         int moveFlags = PackageManager.MOVE_INTERNAL;
1712         boolean fail = false;
1713         int result = PackageManager.MOVE_SUCCEEDED;
1714         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1715     }
1716 
1717     @LargeTest
testMoveAppForwardLocked()1718     public void testMoveAppForwardLocked() throws Exception {
1719         // Do not run on devices with emulated external storage.
1720         if (Environment.isExternalStorageEmulated()) {
1721             return;
1722         }
1723 
1724         int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
1725         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1726         boolean fail = false;
1727         int result = PackageManager.MOVE_SUCCEEDED;
1728         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1729     }
1730 
1731     @LargeTest
testMoveAppFailInternalToExternalDelete()1732     public void testMoveAppFailInternalToExternalDelete() throws Exception {
1733         // Do not run on devices with emulated external storage.
1734         if (Environment.isExternalStorageEmulated()) {
1735             return;
1736         }
1737 
1738         int installFlags = 0;
1739         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1740         boolean fail = true;
1741         final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST;
1742 
1743         int rawResId = R.raw.install;
1744         int origDefaultLoc = getDefaultInstallLoc();
1745         InstallParams ip = null;
1746         try {
1747             PackageManager pm = getPm();
1748             setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1749             // Install first
1750             ip = installFromRawResource("install.apk", R.raw.install, installFlags, false,
1751                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1752             // Delete the package now retaining data.
1753             GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1754             invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
1755             assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1756         } catch (Exception e) {
1757             failStr(e);
1758         } finally {
1759             if (ip != null) {
1760                 cleanUpInstall(ip);
1761             }
1762             // Restore default install location
1763             setInstallLoc(origDefaultLoc);
1764         }
1765     }
1766 
1767     /*
1768      * Test that an install error code is returned when media is unmounted
1769      * and package installed on sdcard via package manager flag.
1770      */
1771     @LargeTest
testInstallSdcardUnmount()1772     public void testInstallSdcardUnmount() throws Exception {
1773         // Do not run on devices with emulated external storage.
1774         if (Environment.isExternalStorageEmulated()) {
1775             return;
1776         }
1777 
1778         boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1779         try {
1780             // Unmount sdcard
1781             assertTrue(unmountMedia());
1782             // Try to install and make sure an error code is returned.
1783             installFromRawResource("install.apk", R.raw.install,
1784                     PackageManager.INSTALL_EXTERNAL, false,
1785                     true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
1786                     PackageInfo.INSTALL_LOCATION_AUTO);
1787         } finally {
1788             // Restore original media state
1789             if (origState) {
1790                 mountMedia();
1791             } else {
1792                 unmountMedia();
1793             }
1794         }
1795     }
1796 
1797     /*
1798      * Unmount sdcard. Try installing an app with manifest option to install
1799      * on sdcard. Make sure it gets installed on internal flash.
1800      */
1801     @LargeTest
testInstallManifestSdcardUnmount()1802     public void testInstallManifestSdcardUnmount() throws Exception {
1803         // Do not run on devices with emulated external storage.
1804         if (Environment.isExternalStorageEmulated()) {
1805             return;
1806         }
1807 
1808         boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
1809         try {
1810             // Unmount sdcard
1811             assertTrue(unmountMedia());
1812             InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
1813             installFromRawResource(ip, 0, true, false, -1,
1814                     PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1815         } finally {
1816             // Restore original media state
1817             if (origState) {
1818                 mountMedia();
1819             } else {
1820                 unmountMedia();
1821             }
1822         }
1823     }
1824 
1825     /*---------- Recommended install location tests ----*/
1826     /*
1827      * PrecedenceSuffixes:
1828      * Flag : FlagI, FlagE, FlagF
1829      * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1830      * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1831      * Existing: Existing suffix absent if not existing.
1832      * User: UserI, UserE, UserA, User suffix absent if not existing.
1833      *
1834      */
1835 
1836     /*
1837      * Install an app on internal flash
1838      */
1839     @LargeTest
testFlagI()1840     public void testFlagI() throws Exception {
1841         sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1842     }
1843 
1844     /*
1845      * Install an app on sdcard.
1846      */
1847     @LargeTest
testFlagE()1848     public void testFlagE() throws Exception {
1849         // Do not run on devices with emulated external storage.
1850         if (Environment.isExternalStorageEmulated()) {
1851             return;
1852         }
1853 
1854         sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
1855     }
1856 
1857     /*
1858      * Install an app forward-locked.
1859      */
1860     @LargeTest
testFlagF()1861     public void testFlagF() throws Exception {
1862         sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
1863     }
1864 
1865     /*
1866      * Install an app with both internal and external flags set. should fail
1867      */
1868     @LargeTest
testFlagIE()1869     public void testFlagIE() throws Exception {
1870         installFromRawResource("install.apk", R.raw.install,
1871                 PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
1872                 false,
1873                 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1874                 PackageInfo.INSTALL_LOCATION_AUTO);
1875     }
1876 
1877     /*
1878      * Install an app with both internal and forward-lock flags set.
1879      */
1880     @LargeTest
testFlagIF()1881     public void testFlagIF() throws Exception {
1882         sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1883                 | PackageManager.INSTALL_INTERNAL, true);
1884     }
1885 
1886     /*
1887      * Install an app with both external and forward-lock flags set.
1888      */
1889     @LargeTest
testFlagEF()1890     public void testFlagEF() throws Exception {
1891         // Do not run on devices with emulated external storage.
1892         if (Environment.isExternalStorageEmulated()) {
1893             return;
1894         }
1895 
1896         sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
1897                 | PackageManager.INSTALL_EXTERNAL, true);
1898     }
1899 
1900     /*
1901      * Install an app with both internal and external flags set with forward
1902      * lock. Should fail.
1903      */
1904     @LargeTest
testFlagIEF()1905     public void testFlagIEF() throws Exception {
1906         installFromRawResource("install.apk", R.raw.install,
1907                 PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
1908                 PackageManager.INSTALL_EXTERNAL,
1909                 false,
1910                 true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
1911                 PackageInfo.INSTALL_LOCATION_AUTO);
1912     }
1913 
1914     /*
1915      * Install an app with both internal and manifest option set.
1916      * should install on internal.
1917      */
1918     @LargeTest
testFlagIManifestI()1919     public void testFlagIManifestI() throws Exception {
1920         installFromRawResource("install.apk", R.raw.install_loc_internal,
1921                 PackageManager.INSTALL_INTERNAL,
1922                 true,
1923                 false, -1,
1924                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1925     }
1926     /*
1927      * Install an app with both internal and manifest preference for
1928      * preferExternal. Should install on internal.
1929      */
1930     @LargeTest
testFlagIManifestE()1931     public void testFlagIManifestE() throws Exception {
1932         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1933                 PackageManager.INSTALL_INTERNAL,
1934                 true,
1935                 false, -1,
1936                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1937     }
1938     /*
1939      * Install an app with both internal and manifest preference for
1940      * auto. should install internal.
1941      */
1942     @LargeTest
testFlagIManifestA()1943     public void testFlagIManifestA() throws Exception {
1944         installFromRawResource("install.apk", R.raw.install_loc_auto,
1945                 PackageManager.INSTALL_INTERNAL,
1946                 true,
1947                 false, -1,
1948                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1949     }
1950     /*
1951      * Install an app with both external and manifest option set.
1952      * should install externally.
1953      */
1954     @LargeTest
testFlagEManifestI()1955     public void testFlagEManifestI() throws Exception {
1956         // Do not run on devices with emulated external storage.
1957         if (Environment.isExternalStorageEmulated()) {
1958             return;
1959         }
1960 
1961         installFromRawResource("install.apk", R.raw.install_loc_internal,
1962                 PackageManager.INSTALL_EXTERNAL,
1963                 true,
1964                 false, -1,
1965                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1966     }
1967 
1968     /*
1969      * Install an app with both external and manifest preference for
1970      * preferExternal. Should install externally.
1971      */
1972     @LargeTest
testFlagEManifestE()1973     public void testFlagEManifestE() throws Exception {
1974         // Do not run on devices with emulated external storage.
1975         if (Environment.isExternalStorageEmulated()) {
1976             return;
1977         }
1978 
1979         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1980                 PackageManager.INSTALL_EXTERNAL,
1981                 true,
1982                 false, -1,
1983                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1984     }
1985 
1986     /*
1987      * Install an app with both external and manifest preference for
1988      * auto. should install on external media.
1989      */
1990     @LargeTest
testFlagEManifestA()1991     public void testFlagEManifestA() throws Exception {
1992         // Do not run on devices with emulated external storage.
1993         if (Environment.isExternalStorageEmulated()) {
1994             return;
1995         }
1996 
1997         installFromRawResource("install.apk", R.raw.install_loc_auto,
1998                 PackageManager.INSTALL_EXTERNAL,
1999                 true,
2000                 false, -1,
2001                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2002     }
2003 
2004     /*
2005      * Install an app with fwd locked flag set and install location set to
2006      * internal. should install internally.
2007      */
2008     @LargeTest
testFlagFManifestI()2009     public void testFlagFManifestI() throws Exception {
2010         installFromRawResource("install.apk", R.raw.install_loc_internal,
2011                 PackageManager.INSTALL_FORWARD_LOCK,
2012                 true,
2013                 false, -1,
2014                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2015     }
2016 
2017     /*
2018      * Install an app with fwd locked flag set and install location set to
2019      * preferExternal. Should install externally.
2020      */
2021     @LargeTest
testFlagFManifestE()2022     public void testFlagFManifestE() throws Exception {
2023         // Do not run on devices with emulated external storage.
2024         if (Environment.isExternalStorageEmulated()) {
2025             return;
2026         }
2027 
2028         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2029                 PackageManager.INSTALL_FORWARD_LOCK,
2030                 true,
2031                 false, -1,
2032                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2033     }
2034 
2035     /*
2036      * Install an app with fwd locked flag set and install location set to auto.
2037      * should install externally.
2038      */
2039     @LargeTest
testFlagFManifestA()2040     public void testFlagFManifestA() throws Exception {
2041         // Do not run on devices with emulated external storage.
2042         if (Environment.isExternalStorageEmulated()) {
2043             return;
2044         }
2045 
2046         installFromRawResource("install.apk", R.raw.install_loc_auto,
2047                 PackageManager.INSTALL_FORWARD_LOCK,
2048                 true,
2049                 false, -1,
2050                 PackageInfo.INSTALL_LOCATION_AUTO);
2051     }
2052 
2053     /*
2054      * The following test functions verify install location for existing apps.
2055      * ie existing app can be installed internally or externally. If install
2056      * flag is explicitly set it should override current location. If manifest location
2057      * is set, that should over ride current location too. if not the existing install
2058      * location should be honoured.
2059      * testFlagI/E/F/ExistingI/E -
2060      */
2061     @LargeTest
testFlagIExistingI()2062     public void testFlagIExistingI() throws Exception {
2063         int iFlags = PackageManager.INSTALL_INTERNAL;
2064         int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2065         // First install.
2066         installFromRawResource("install.apk", R.raw.install,
2067                 iFlags,
2068                 false,
2069                 false, -1,
2070                 -1);
2071         // Replace now
2072         installFromRawResource("install.apk", R.raw.install,
2073                 rFlags,
2074                 true,
2075                 false, -1,
2076                 -1);
2077     }
2078 
2079     @LargeTest
testFlagIExistingE()2080     public void testFlagIExistingE() throws Exception {
2081         // Do not run on devices with emulated external storage.
2082         if (Environment.isExternalStorageEmulated()) {
2083             return;
2084         }
2085 
2086         int iFlags = PackageManager.INSTALL_EXTERNAL;
2087         int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2088         // First install.
2089         installFromRawResource("install.apk", R.raw.install,
2090                 iFlags,
2091                 false,
2092                 false, -1,
2093                 -1);
2094         // Replace now
2095         installFromRawResource("install.apk", R.raw.install,
2096                 rFlags,
2097                 true,
2098                 false, -1,
2099                 -1);
2100     }
2101 
2102     @LargeTest
testFlagEExistingI()2103     public void testFlagEExistingI() throws Exception {
2104         // Do not run on devices with emulated external storage.
2105         if (Environment.isExternalStorageEmulated()) {
2106             return;
2107         }
2108 
2109         int iFlags = PackageManager.INSTALL_INTERNAL;
2110         int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2111         // First install.
2112         installFromRawResource("install.apk", R.raw.install,
2113                 iFlags,
2114                 false,
2115                 false, -1,
2116                 -1);
2117         // Replace now
2118         installFromRawResource("install.apk", R.raw.install,
2119                 rFlags,
2120                 true,
2121                 false, -1,
2122                 -1);
2123     }
2124 
2125     @LargeTest
testFlagEExistingE()2126     public void testFlagEExistingE() throws Exception {
2127         // Do not run on devices with emulated external storage.
2128         if (Environment.isExternalStorageEmulated()) {
2129             return;
2130         }
2131 
2132         int iFlags = PackageManager.INSTALL_EXTERNAL;
2133         int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
2134         // First install.
2135         installFromRawResource("install.apk", R.raw.install,
2136                 iFlags,
2137                 false,
2138                 false, -1,
2139                 -1);
2140         // Replace now
2141         installFromRawResource("install.apk", R.raw.install,
2142                 rFlags,
2143                 true,
2144                 false, -1,
2145                 -1);
2146     }
2147 
2148     @Suppress
2149     @LargeTest
testFlagFExistingI()2150     public void testFlagFExistingI() throws Exception {
2151         int iFlags = PackageManager.INSTALL_INTERNAL;
2152         int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2153         // First install.
2154         installFromRawResource("install.apk", R.raw.install,
2155                 iFlags,
2156                 false,
2157                 false, -1,
2158                 -1);
2159         // Replace now
2160         installFromRawResource("install.apk", R.raw.install,
2161                 rFlags,
2162                 true,
2163                 false, -1,
2164                 -1);
2165     }
2166 
2167     @LargeTest
testFlagFExistingE()2168     public void testFlagFExistingE() throws Exception {
2169         // Do not run on devices with emulated external storage.
2170         if (Environment.isExternalStorageEmulated()) {
2171             return;
2172         }
2173 
2174         int iFlags = PackageManager.INSTALL_EXTERNAL;
2175         int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
2176         // First install.
2177         installFromRawResource("install.apk", R.raw.install,
2178                 iFlags,
2179                 false,
2180                 false, -1,
2181                 -1);
2182         // Replace now
2183         installFromRawResource("install.apk", R.raw.install,
2184                 rFlags,
2185                 true,
2186                 false, -1,
2187                 -1);
2188     }
2189 
2190     /*
2191      * The following set of tests verify the installation of apps with
2192      * install location attribute set to internalOnly, preferExternal and auto.
2193      * The manifest option should dictate the install location.
2194      * public void testManifestI/E/A
2195      * TODO out of memory fall back behaviour.
2196      */
2197     @LargeTest
testManifestI()2198     public void testManifestI() throws Exception {
2199         installFromRawResource("install.apk", R.raw.install_loc_internal,
2200                 0,
2201                 true,
2202                 false, -1,
2203                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2204     }
2205 
2206     @LargeTest
testManifestE()2207     public void testManifestE() throws Exception {
2208         // Do not run on devices with emulated external storage.
2209         if (Environment.isExternalStorageEmulated()) {
2210             return;
2211         }
2212 
2213         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2214                 0,
2215                 true,
2216                 false, -1,
2217                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2218     }
2219 
2220     @LargeTest
testManifestA()2221     public void testManifestA() throws Exception {
2222         installFromRawResource("install.apk", R.raw.install_loc_auto,
2223                 0,
2224                 true,
2225                 false, -1,
2226                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2227     }
2228 
2229     /*
2230      * The following set of tests verify the installation of apps
2231      * with install location attribute set to internalOnly, preferExternal and auto
2232      * for already existing apps. The manifest option should take precedence.
2233      * TODO add out of memory fall back behaviour.
2234      * testManifestI/E/AExistingI/E
2235      */
2236     @LargeTest
testManifestIExistingI()2237     public void testManifestIExistingI() throws Exception {
2238         int iFlags = PackageManager.INSTALL_INTERNAL;
2239         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2240         // First install.
2241         installFromRawResource("install.apk", R.raw.install,
2242                 iFlags,
2243                 false,
2244                 false, -1,
2245                 -1);
2246         // Replace now
2247         installFromRawResource("install.apk", R.raw.install_loc_internal,
2248                 rFlags,
2249                 true,
2250                 false, -1,
2251                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2252     }
2253 
2254     @LargeTest
testManifestIExistingE()2255     public void testManifestIExistingE() throws Exception {
2256         // Do not run on devices with emulated external storage.
2257         if (Environment.isExternalStorageEmulated()) {
2258             return;
2259         }
2260 
2261         int iFlags = PackageManager.INSTALL_EXTERNAL;
2262         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2263         // First install.
2264         installFromRawResource("install.apk", R.raw.install,
2265                 iFlags,
2266                 false,
2267                 false, -1,
2268                 -1);
2269         // Replace now
2270         installFromRawResource("install.apk", R.raw.install_loc_internal,
2271                 rFlags,
2272                 true,
2273                 false, -1,
2274                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2275     }
2276 
2277     @LargeTest
testManifestEExistingI()2278     public void testManifestEExistingI() throws Exception {
2279         // Do not run on devices with emulated external storage.
2280         if (Environment.isExternalStorageEmulated()) {
2281             return;
2282         }
2283 
2284         int iFlags = PackageManager.INSTALL_INTERNAL;
2285         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2286         // First install.
2287         installFromRawResource("install.apk", R.raw.install,
2288                 iFlags,
2289                 false,
2290                 false, -1,
2291                 -1);
2292         // Replace now
2293         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2294                 rFlags,
2295                 true,
2296                 false, -1,
2297                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2298     }
2299 
2300     @LargeTest
testManifestEExistingE()2301     public void testManifestEExistingE() throws Exception {
2302         // Do not run on devices with emulated external storage.
2303         if (Environment.isExternalStorageEmulated()) {
2304             return;
2305         }
2306 
2307         int iFlags = PackageManager.INSTALL_EXTERNAL;
2308         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2309         // First install.
2310         installFromRawResource("install.apk", R.raw.install,
2311                 iFlags,
2312                 false,
2313                 false, -1,
2314                 -1);
2315         // Replace now
2316         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
2317                 rFlags,
2318                 true,
2319                 false, -1,
2320                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2321     }
2322 
2323     @LargeTest
testManifestAExistingI()2324     public void testManifestAExistingI() throws Exception {
2325         int iFlags = PackageManager.INSTALL_INTERNAL;
2326         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2327         // First install.
2328         installFromRawResource("install.apk", R.raw.install,
2329                 iFlags,
2330                 false,
2331                 false, -1,
2332                 -1);
2333         // Replace now
2334         installFromRawResource("install.apk", R.raw.install_loc_auto,
2335                 rFlags,
2336                 true,
2337                 false, -1,
2338                 PackageInfo.INSTALL_LOCATION_AUTO);
2339     }
2340 
2341     @LargeTest
testManifestAExistingE()2342     public void testManifestAExistingE() throws Exception {
2343         // Do not run on devices with emulated external storage.
2344         if (Environment.isExternalStorageEmulated()) {
2345             return;
2346         }
2347 
2348         int iFlags = PackageManager.INSTALL_EXTERNAL;
2349         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2350         // First install.
2351         installFromRawResource("install.apk", R.raw.install,
2352                 iFlags,
2353                 false,
2354                 false, -1,
2355                 -1);
2356         // Replace now
2357         installFromRawResource("install.apk", R.raw.install_loc_auto,
2358                 rFlags,
2359                 true,
2360                 false, -1,
2361                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2362     }
2363 
2364     /*
2365      * The following set of tests check install location for existing
2366      * application based on user setting.
2367      */
getExpectedInstallLocation(int userSetting)2368     private int getExpectedInstallLocation(int userSetting) {
2369         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2370         boolean enable = getUserSettingSetInstallLocation();
2371         if (enable) {
2372             if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
2373                 iloc = PackageInfo.INSTALL_LOCATION_AUTO;
2374             } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
2375                 iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
2376             } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
2377                 iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
2378             }
2379         }
2380         return iloc;
2381     }
2382 
setExistingXUserX(int userSetting, int iFlags, int iloc)2383     private void setExistingXUserX(int userSetting, int iFlags, int iloc) throws Exception {
2384         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2385         // First install.
2386         installFromRawResource("install.apk", R.raw.install,
2387                 iFlags,
2388                 false,
2389                 false, -1,
2390                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2391         int origSetting = getDefaultInstallLoc();
2392         try {
2393             // Set user setting
2394             setInstallLoc(userSetting);
2395             // Replace now
2396             installFromRawResource("install.apk", R.raw.install,
2397                     rFlags,
2398                     true,
2399                     false, -1,
2400                     iloc);
2401         } finally {
2402             setInstallLoc(origSetting);
2403         }
2404     }
2405     @LargeTest
testExistingIUserI()2406     public void testExistingIUserI() throws Exception {
2407         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2408         int iFlags = PackageManager.INSTALL_INTERNAL;
2409         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2410     }
2411 
2412     @LargeTest
testExistingIUserE()2413     public void testExistingIUserE() throws Exception {
2414         // Do not run on devices with emulated external storage.
2415         if (Environment.isExternalStorageEmulated()) {
2416             return;
2417         }
2418 
2419         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2420         int iFlags = PackageManager.INSTALL_INTERNAL;
2421         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2422     }
2423 
2424     @LargeTest
testExistingIUserA()2425     public void testExistingIUserA() throws Exception {
2426         int userSetting = PackageHelper.APP_INSTALL_AUTO;
2427         int iFlags = PackageManager.INSTALL_INTERNAL;
2428         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2429     }
2430 
2431     @LargeTest
testExistingEUserI()2432     public void testExistingEUserI() throws Exception {
2433         // Do not run on devices with emulated external storage.
2434         if (Environment.isExternalStorageEmulated()) {
2435             return;
2436         }
2437 
2438         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2439         int iFlags = PackageManager.INSTALL_EXTERNAL;
2440         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2441     }
2442 
2443     @LargeTest
testExistingEUserE()2444     public void testExistingEUserE() throws Exception {
2445         // Do not run on devices with emulated external storage.
2446         if (Environment.isExternalStorageEmulated()) {
2447             return;
2448         }
2449 
2450         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2451         int iFlags = PackageManager.INSTALL_EXTERNAL;
2452         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2453     }
2454 
2455     @LargeTest
testExistingEUserA()2456     public void testExistingEUserA() throws Exception {
2457         // Do not run on devices with emulated external storage.
2458         if (Environment.isExternalStorageEmulated()) {
2459             return;
2460         }
2461 
2462         int userSetting = PackageHelper.APP_INSTALL_AUTO;
2463         int iFlags = PackageManager.INSTALL_EXTERNAL;
2464         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
2465     }
2466 
2467     /*
2468      * The following set of tests verify that the user setting defines
2469      * the install location.
2470      *
2471      */
getUserSettingSetInstallLocation()2472     private boolean getUserSettingSetInstallLocation() {
2473         try {
2474             return Settings.Global.getInt(
2475                     mContext.getContentResolver(), Settings.Global.SET_INSTALL_LOCATION) != 0;
2476         } catch (SettingNotFoundException e1) {
2477         }
2478         return false;
2479     }
2480 
setUserSettingSetInstallLocation(boolean value)2481     private void setUserSettingSetInstallLocation(boolean value) {
2482         Settings.Global.putInt(mContext.getContentResolver(),
2483                 Settings.Global.SET_INSTALL_LOCATION, value ? 1 : 0);
2484     }
2485 
setUserX(boolean enable, int userSetting, int iloc)2486     private void setUserX(boolean enable, int userSetting, int iloc) throws Exception {
2487         boolean origUserSetting = getUserSettingSetInstallLocation();
2488         int origSetting = getDefaultInstallLoc();
2489         try {
2490             setUserSettingSetInstallLocation(enable);
2491             // Set user setting
2492             setInstallLoc(userSetting);
2493             // Replace now
2494             installFromRawResource("install.apk", R.raw.install,
2495                     0,
2496                     true,
2497                     false, -1,
2498                     iloc);
2499         } finally {
2500             // Restore original setting
2501             setUserSettingSetInstallLocation(origUserSetting);
2502             setInstallLoc(origSetting);
2503         }
2504     }
2505     @LargeTest
testUserI()2506     public void testUserI() throws Exception {
2507         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2508         int iloc = getExpectedInstallLocation(userSetting);
2509         setUserX(true, userSetting, iloc);
2510     }
2511 
2512     @LargeTest
testUserE()2513     public void testUserE() throws Exception {
2514         // Do not run on devices with emulated external storage.
2515         if (Environment.isExternalStorageEmulated()) {
2516             return;
2517         }
2518 
2519         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2520         int iloc = getExpectedInstallLocation(userSetting);
2521         setUserX(true, userSetting, iloc);
2522     }
2523 
2524     @LargeTest
testUserA()2525     public void testUserA() throws Exception {
2526         int userSetting = PackageHelper.APP_INSTALL_AUTO;
2527         int iloc = getExpectedInstallLocation(userSetting);
2528         setUserX(true, userSetting, iloc);
2529     }
2530 
2531     /*
2532      * The following set of tests turn on/off the basic
2533      * user setting for turning on install location.
2534      */
2535     @LargeTest
testUserPrefOffUserI()2536     public void testUserPrefOffUserI() throws Exception {
2537         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
2538         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2539         setUserX(false, userSetting, iloc);
2540     }
2541 
2542     @LargeTest
testUserPrefOffUserE()2543     public void testUserPrefOffUserE() throws Exception {
2544         // Do not run on devices with emulated external storage.
2545         if (Environment.isExternalStorageEmulated()) {
2546             return;
2547         }
2548 
2549         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
2550         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2551         setUserX(false, userSetting, iloc);
2552     }
2553 
2554     @LargeTest
testUserPrefOffA()2555     public void testUserPrefOffA() throws Exception {
2556         int userSetting = PackageHelper.APP_INSTALL_AUTO;
2557         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
2558         setUserX(false, userSetting, iloc);
2559     }
2560 
2561     static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
2562         PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
2563         PERM_DEFINED,
2564         "com.android.frameworks.coretests.NORMAL",
2565         "com.android.frameworks.coretests.DANGEROUS",
2566         "com.android.frameworks.coretests.SIGNATURE",
2567     };
2568 
2569     static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
2570         PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm",
2571         PERM_UNDEFINED,
2572         "com.android.frameworks.coretests.NORMAL",
2573         "com.android.frameworks.coretests.DANGEROUS",
2574         "com.android.frameworks.coretests.SIGNATURE",
2575     };
2576 
2577     static final String BASE_PERMISSIONS_USED[] = new String[] {
2578         PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2579         PERM_USED,
2580         "com.android.frameworks.coretests.NORMAL",
2581         "com.android.frameworks.coretests.DANGEROUS",
2582         "com.android.frameworks.coretests.SIGNATURE",
2583     };
2584 
2585     static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
2586         PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2587         PERM_NOTUSED,
2588         "com.android.frameworks.coretests.NORMAL",
2589         "com.android.frameworks.coretests.DANGEROUS",
2590         "com.android.frameworks.coretests.SIGNATURE",
2591     };
2592 
2593     static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
2594         PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
2595         PERM_USED,
2596         "com.android.frameworks.coretests.SIGNATURE",
2597         PERM_NOTUSED,
2598         "com.android.frameworks.coretests.NORMAL",
2599         "com.android.frameworks.coretests.DANGEROUS",
2600     };
2601 
2602     /*
2603      * Ensure that permissions are properly declared.
2604      */
2605     @LargeTest
testInstallDeclaresPermissions()2606     public void testInstallDeclaresPermissions() throws Exception {
2607         InstallParams ip = null;
2608         InstallParams ip2 = null;
2609         try {
2610             // **: Upon installing a package, are its declared permissions published?
2611 
2612             int iFlags = PackageManager.INSTALL_INTERNAL;
2613             int iApk = R.raw.install_decl_perm;
2614             ip = installFromRawResource("install.apk", iApk,
2615                     iFlags, false,
2616                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2617             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2618             assertPermissions(BASE_PERMISSIONS_DEFINED);
2619 
2620             // **: Upon installing package, are its permissions granted?
2621 
2622             int i2Flags = PackageManager.INSTALL_INTERNAL;
2623             int i2Apk = R.raw.install_use_perm_good;
2624             ip2 = installFromRawResource("install2.apk", i2Apk,
2625                     i2Flags, false,
2626                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2627             assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2628             assertPermissions(BASE_PERMISSIONS_USED);
2629 
2630             // **: Upon removing but not deleting, are permissions retained?
2631 
2632             GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
2633 
2634             try {
2635                 invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
2636             } catch (Exception e) {
2637                 failStr(e);
2638             }
2639             assertPermissions(BASE_PERMISSIONS_DEFINED);
2640             assertPermissions(BASE_PERMISSIONS_USED);
2641 
2642             // **: Upon re-installing, are permissions retained?
2643 
2644             ip = installFromRawResource("install.apk", iApk,
2645                     iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2646                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2647             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2648             assertPermissions(BASE_PERMISSIONS_DEFINED);
2649             assertPermissions(BASE_PERMISSIONS_USED);
2650 
2651             // **: Upon deleting package, are all permissions removed?
2652 
2653             try {
2654                 invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2655                 ip = null;
2656             } catch (Exception e) {
2657                 failStr(e);
2658             }
2659             assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2660             assertPermissions(BASE_PERMISSIONS_NOTUSED);
2661 
2662             // **: Delete package using permissions; nothing to check here.
2663 
2664             GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
2665             try {
2666                 invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2667                 ip2 = null;
2668             } catch (Exception e) {
2669                 failStr(e);
2670             }
2671 
2672             // **: Re-install package using permissions; no permissions can be granted.
2673 
2674             ip2 = installFromRawResource("install2.apk", i2Apk,
2675                     i2Flags, false,
2676                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2677             assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2678             assertPermissions(BASE_PERMISSIONS_NOTUSED);
2679 
2680             // **: Upon installing declaring package, are sig permissions granted
2681             // to other apps (but not other perms)?
2682 
2683             ip = installFromRawResource("install.apk", iApk,
2684                     iFlags, false,
2685                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2686             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2687             assertPermissions(BASE_PERMISSIONS_DEFINED);
2688             assertPermissions(BASE_PERMISSIONS_SIGUSED);
2689 
2690             // **: Re-install package using permissions; are all permissions granted?
2691 
2692             ip2 = installFromRawResource("install2.apk", i2Apk,
2693                     i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
2694                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2695             assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
2696             assertPermissions(BASE_PERMISSIONS_NOTUSED);
2697 
2698             // **: Upon deleting package, are all permissions removed?
2699 
2700             try {
2701                 invokeDeletePackage(ip.pkg.packageName, 0, receiver);
2702                 ip = null;
2703             } catch (Exception e) {
2704                 failStr(e);
2705             }
2706             assertPermissions(BASE_PERMISSIONS_UNDEFINED);
2707             assertPermissions(BASE_PERMISSIONS_NOTUSED);
2708 
2709             // **: Delete package using permissions; nothing to check here.
2710 
2711             try {
2712                 invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
2713                 ip2 = null;
2714             } catch (Exception e) {
2715                 failStr(e);
2716             }
2717 
2718         } finally {
2719             if (ip2 != null) {
2720                 cleanUpInstall(ip2);
2721             }
2722             if (ip != null) {
2723                 cleanUpInstall(ip);
2724             }
2725         }
2726     }
2727 
2728     /*
2729      * Ensure that permissions are properly declared.
2730      */
2731     @LargeTest
testInstallOnSdPermissionsUnmount()2732     public void testInstallOnSdPermissionsUnmount() throws Exception {
2733         InstallParams ip = null;
2734         boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2735         try {
2736             // **: Upon installing a package, are its declared permissions published?
2737             int iFlags = PackageManager.INSTALL_INTERNAL;
2738             int iApk = R.raw.install_decl_perm;
2739             ip = installFromRawResource("install.apk", iApk,
2740                     iFlags, false,
2741                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2742             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
2743             assertPermissions(BASE_PERMISSIONS_DEFINED);
2744             // Unmount media here
2745             assertTrue(unmountMedia());
2746             // Mount media again
2747             mountMedia();
2748             //Check permissions now
2749             assertPermissions(BASE_PERMISSIONS_DEFINED);
2750         } finally {
2751             if (ip != null) {
2752                 cleanUpInstall(ip);
2753             }
2754         }
2755     }
2756 
2757     /* This test creates a stale container via MountService and then installs
2758      * a package and verifies that the stale container is cleaned up and install
2759      * is successful.
2760      * Please note that this test is very closely tied to the framework's
2761      * naming convention for secure containers.
2762      */
2763     @LargeTest
testInstallSdcardStaleContainer()2764     public void testInstallSdcardStaleContainer() throws Exception {
2765         // Do not run on devices with emulated external storage.
2766         if (Environment.isExternalStorageEmulated()) {
2767             return;
2768         }
2769 
2770         boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2771         try {
2772             // Mount media first
2773             mountMedia();
2774             String outFileName = "install.apk";
2775             int rawResId = R.raw.install;
2776             PackageManager pm = mContext.getPackageManager();
2777             File filesDir = mContext.getFilesDir();
2778             File outFile = new File(filesDir, outFileName);
2779             Uri packageURI = getInstallablePackage(rawResId, outFile);
2780             PackageParser.Package pkg = parsePackage(packageURI);
2781             assertNotNull(pkg);
2782             // Install an app on sdcard.
2783             installFromRawResource(outFileName, rawResId,
2784                     PackageManager.INSTALL_EXTERNAL, false,
2785                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2786             // Unmount sdcard
2787             unmountMedia();
2788             // Delete the app on sdcard to leave a stale container on sdcard.
2789             GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
2790             assertTrue(invokeDeletePackage(pkg.packageName, 0, receiver));
2791             mountMedia();
2792             // Reinstall the app and make sure it gets installed.
2793             installFromRawResource(outFileName, rawResId,
2794                     PackageManager.INSTALL_EXTERNAL, true,
2795                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2796         } catch (Exception e) {
2797             failStr(e.getMessage());
2798         } finally {
2799             if (origMediaState) {
2800                 mountMedia();
2801             } else {
2802                 unmountMedia();
2803             }
2804 
2805         }
2806     }
2807 
2808     /* This test installs an application on sdcard and unmounts media.
2809      * The app is then re-installed on internal storage. The sdcard is mounted
2810      * and verified that the re-installation on internal storage takes precedence.
2811      */
2812     @LargeTest
testInstallSdcardStaleContainerReinstall()2813     public void testInstallSdcardStaleContainerReinstall() throws Exception {
2814         // Do not run on devices with emulated external storage.
2815         if (Environment.isExternalStorageEmulated()) {
2816             return;
2817         }
2818 
2819         boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
2820         try {
2821             // Mount media first
2822             mountMedia();
2823             String outFileName = "install.apk";
2824             int rawResId = R.raw.install;
2825             PackageManager pm = mContext.getPackageManager();
2826             File filesDir = mContext.getFilesDir();
2827             File outFile = new File(filesDir, outFileName);
2828             Uri packageURI = getInstallablePackage(rawResId, outFile);
2829             PackageParser.Package pkg = parsePackage(packageURI);
2830             assertNotNull(pkg);
2831             // Install an app on sdcard.
2832             installFromRawResource(outFileName, rawResId,
2833                     PackageManager.INSTALL_EXTERNAL, false,
2834                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2835             // Unmount sdcard
2836             unmountMedia();
2837             // Reinstall the app and make sure it gets installed on internal storage.
2838             installFromRawResource(outFileName, rawResId,
2839                     PackageManager.INSTALL_REPLACE_EXISTING, false,
2840                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2841             mountMedia();
2842             // Verify that the app installed is on internal storage.
2843             assertInstall(pkg, 0, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2844         } catch (Exception e) {
2845             failStr(e.getMessage());
2846         } finally {
2847             if (origMediaState) {
2848                 mountMedia();
2849             } else {
2850                 unmountMedia();
2851             }
2852         }
2853     }
2854 
2855     /*
2856      * The following series of tests are related to upgrading apps with
2857      * different certificates.
2858      */
2859     private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
2860 
2861     private int APP1_CERT1 = R.raw.install_app1_cert1;
2862 
2863     private int APP1_CERT2 = R.raw.install_app1_cert2;
2864 
2865     private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
2866 
2867     private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
2868 
2869     private int APP1_CERT3 = R.raw.install_app1_cert3;
2870 
2871     private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
2872 
2873     private int APP2_CERT1 = R.raw.install_app2_cert1;
2874 
2875     private int APP2_CERT2 = R.raw.install_app2_cert2;
2876 
2877     private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
2878 
2879     private int APP2_CERT3 = R.raw.install_app2_cert3;
2880 
replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode)2881     private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail,
2882             int retCode) throws Exception {
2883         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2884         String apk1Name = "install1.apk";
2885         String apk2Name = "install2.apk";
2886         PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2887         try {
2888             InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
2889                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2890             installFromRawResource(apk2Name, apk2, rFlags, false,
2891                     fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2892             return ip;
2893         } catch (Exception e) {
2894             failStr(e.getMessage());
2895         } finally {
2896             if (cleanUp) {
2897                 cleanUpInstall(pkg1.packageName);
2898             }
2899         }
2900         return null;
2901     }
2902 
2903     /*
2904      * Test that an app signed with two certificates can be upgraded by the
2905      * same app signed with two certificates.
2906      */
2907     @LargeTest
testReplaceMatchAllCerts()2908     public void testReplaceMatchAllCerts() throws Exception {
2909         replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
2910     }
2911 
2912     /*
2913      * Test that an app signed with two certificates cannot be upgraded
2914      * by an app signed with a different certificate.
2915      */
2916     @LargeTest
testReplaceMatchNoCerts1()2917     public void testReplaceMatchNoCerts1() throws Exception {
2918         replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
2919                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2920     }
2921 
2922     /*
2923      * Test that an app signed with two certificates cannot be upgraded
2924      * by an app signed with a different certificate.
2925      */
2926     @LargeTest
testReplaceMatchNoCerts2()2927     public void testReplaceMatchNoCerts2() throws Exception {
2928         replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
2929                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2930     }
2931 
2932     /*
2933      * Test that an app signed with two certificates cannot be upgraded by
2934      * an app signed with a subset of initial certificates.
2935      */
2936     @LargeTest
testReplaceMatchSomeCerts1()2937     public void testReplaceMatchSomeCerts1() throws Exception {
2938         replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
2939                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2940     }
2941 
2942     /*
2943      * Test that an app signed with two certificates cannot be upgraded by
2944      * an app signed with the last certificate.
2945      */
2946     @LargeTest
testReplaceMatchSomeCerts2()2947     public void testReplaceMatchSomeCerts2() throws Exception {
2948         replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
2949                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2950     }
2951 
2952     /*
2953      * Test that an app signed with a certificate can be upgraded by app
2954      * signed with a superset of certificates.
2955      */
2956     @LargeTest
testReplaceMatchMoreCerts()2957     public void testReplaceMatchMoreCerts() throws Exception {
2958         replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
2959                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2960     }
2961 
2962     /*
2963      * Test that an app signed with a certificate can be upgraded by app
2964      * signed with a superset of certificates. Then verify that the an app
2965      * signed with the original set of certs cannot upgrade the new one.
2966      */
2967     @LargeTest
testReplaceMatchMoreCertsReplaceSomeCerts()2968     public void testReplaceMatchMoreCertsReplaceSomeCerts() throws Exception {
2969         InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
2970                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
2971         try {
2972             int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
2973             installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
2974                     false, -1,
2975                     PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2976         } catch (Exception e) {
2977             failStr(e.getMessage());
2978         } finally {
2979             if (ip != null) {
2980                 cleanUpInstall(ip);
2981             }
2982         }
2983     }
2984 
2985     /**
2986      * The following tests are related to testing KeySets-based key rotation
2987      */
2988     /*
2989      * Check if an apk which does not specify an upgrade-keyset may be upgraded
2990      * by an apk which does
2991      */
testNoKSToUpgradeKS()2992     public void testNoKSToUpgradeKS() throws Exception {
2993         replaceCerts(R.raw.keyset_sa_unone, R.raw.keyset_sa_ua, true, false, -1);
2994     }
2995 
2996     /*
2997      * Check if an apk which does specify an upgrade-keyset may be downgraded to
2998      * an apk which does not
2999      */
testUpgradeKSToNoKS()3000     public void testUpgradeKSToNoKS() throws Exception {
3001         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_unone, true, false, -1);
3002     }
3003 
3004     /*
3005      * Check if an apk signed by a key other than the upgrade keyset can update
3006      * an app
3007      */
testUpgradeKSWithWrongKey()3008     public void testUpgradeKSWithWrongKey() throws Exception {
3009         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sb_ua, true, true,
3010                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
3011     }
3012 
3013     /*
3014      * Check if an apk signed by its signing key, which is not an upgrade key,
3015      * can upgrade an app.
3016      */
testUpgradeKSWithWrongSigningKey()3017     public void testUpgradeKSWithWrongSigningKey() throws Exception {
3018         replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sa_ub, true, true,
3019                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
3020     }
3021 
3022     /*
3023      * Check if an apk signed by its upgrade key, which is not its signing key,
3024      * can upgrade an app.
3025      */
testUpgradeKSWithUpgradeKey()3026     public void testUpgradeKSWithUpgradeKey() throws Exception {
3027         replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sb_ub, true, false, -1);
3028     }
3029     /*
3030      * Check if an apk signed by its upgrade key, which is its signing key, can
3031      * upgrade an app.
3032      */
testUpgradeKSWithSigningUpgradeKey()3033     public void testUpgradeKSWithSigningUpgradeKey() throws Exception {
3034         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_ua, true, false, -1);
3035     }
3036 
3037     /*
3038      * Check if an apk signed by multiple keys, one of which is its upgrade key,
3039      * can upgrade an app.
3040      */
testMultipleUpgradeKSWithUpgradeKey()3041     public void testMultipleUpgradeKSWithUpgradeKey() throws Exception {
3042         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sab_ua, true, false, -1);
3043     }
3044 
3045     /*
3046      * Check if an apk signed by multiple keys, one of which is its signing key,
3047      * but none of which is an upgrade key, can upgrade an app.
3048      */
testMultipleUpgradeKSWithSigningKey()3049     public void testMultipleUpgradeKSWithSigningKey() throws Exception {
3050         replaceCerts(R.raw.keyset_sau_ub, R.raw.keyset_sa_ua, true, true,
3051                 PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
3052     }
3053 
3054     /*
3055      * Check if an apk which defines multiple (two) upgrade keysets is
3056      * upgrade-able by either.
3057      */
testUpgradeKSWithMultipleUpgradeKeySets()3058     public void testUpgradeKSWithMultipleUpgradeKeySets() throws Exception {
3059         replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sa_ua, true, false, -1);
3060         replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sb_ub, true, false, -1);
3061     }
3062 
3063     /*
3064      * Check if an apk's sigs are changed after upgrading with a non-signing
3065      * key.
3066      *
3067      * TODO: consider checking against hard-coded Signatures in the Sig-tests
3068      */
testSigChangeAfterUpgrade()3069     public void testSigChangeAfterUpgrade() throws Exception {
3070         // install original apk and grab sigs
3071         installFromRawResource("tmp.apk", R.raw.keyset_sa_ub,
3072                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3073         PackageManager pm = getPm();
3074         String pkgName = "com.android.frameworks.coretests.keysets";
3075         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3076         assertTrue("Package should only have one signature, sig A",
3077                 pi.signatures.length == 1);
3078         String sigBefore = pi.signatures[0].toCharsString();
3079         // install apk signed by different upgrade KeySet
3080         installFromRawResource("tmp2.apk", R.raw.keyset_sb_ub,
3081                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3082                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3083         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3084         assertTrue("Package should only have one signature, sig B",
3085                 pi.signatures.length == 1);
3086         String sigAfter = pi.signatures[0].toCharsString();
3087         assertFalse("Package signatures did not change after upgrade!",
3088                 sigBefore.equals(sigAfter));
3089         cleanUpInstall(pkgName);
3090     }
3091 
3092     /*
3093      * Check if an apk's sig is the same  after upgrading with a signing
3094      * key.
3095      */
testSigSameAfterUpgrade()3096     public void testSigSameAfterUpgrade() throws Exception {
3097         // install original apk and grab sigs
3098         installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
3099                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3100         PackageManager pm = getPm();
3101         String pkgName = "com.android.frameworks.coretests.keysets";
3102         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3103         assertTrue("Package should only have one signature, sig A",
3104                 pi.signatures.length == 1);
3105         String sigBefore = pi.signatures[0].toCharsString();
3106         // install apk signed by same upgrade KeySet
3107         installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
3108                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3109                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3110         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3111         assertTrue("Package should only have one signature, sig A",
3112                 pi.signatures.length == 1);
3113         String sigAfter = pi.signatures[0].toCharsString();
3114         assertTrue("Package signatures changed after upgrade!",
3115                 sigBefore.equals(sigAfter));
3116         cleanUpInstall(pkgName);
3117     }
3118 
3119     /*
3120      * Check if an apk's sigs are the same after upgrading with an app with
3121      * a subset of the original signing keys.
3122      */
testSigRemovedAfterUpgrade()3123     public void testSigRemovedAfterUpgrade() throws Exception {
3124         // install original apk and grab sigs
3125         installFromRawResource("tmp.apk", R.raw.keyset_sab_ua,
3126                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3127         PackageManager pm = getPm();
3128         String pkgName = "com.android.frameworks.coretests.keysets";
3129         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3130         assertTrue("Package should have two signatures, sig A and sig B",
3131                 pi.signatures.length == 2);
3132         Set<String> sigsBefore = new HashSet<String>();
3133         for (int i = 0; i < pi.signatures.length; i++) {
3134             sigsBefore.add(pi.signatures[i].toCharsString());
3135         }
3136         // install apk signed subset upgrade KeySet
3137         installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
3138                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3139                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3140         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3141         assertTrue("Package should only have one signature, sig A",
3142                 pi.signatures.length == 1);
3143         String sigAfter = pi.signatures[0].toCharsString();
3144         assertTrue("Original package signatures did not contain new sig",
3145                 sigsBefore.contains(sigAfter));
3146         cleanUpInstall(pkgName);
3147     }
3148 
3149     /*
3150      * Check if an apk's sigs are added to after upgrading with an app with
3151      * a superset of the original signing keys.
3152      */
testSigAddedAfterUpgrade()3153     public void testSigAddedAfterUpgrade() throws Exception {
3154         // install original apk and grab sigs
3155         installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
3156                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3157         PackageManager pm = getPm();
3158         String pkgName = "com.android.frameworks.coretests.keysets";
3159         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3160         assertTrue("Package should only have one signature, sig A",
3161                 pi.signatures.length == 1);
3162         String sigBefore = pi.signatures[0].toCharsString();
3163         // install apk signed subset upgrade KeySet
3164         installFromRawResource("tmp2.apk", R.raw.keyset_sab_ua,
3165                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3166                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3167         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
3168         assertTrue("Package should have two signatures, sig A and sig B",
3169                 pi.signatures.length == 2);
3170         Set<String> sigsAfter = new HashSet<String>();
3171         for (int i = 0; i < pi.signatures.length; i++) {
3172             sigsAfter.add(pi.signatures[i].toCharsString());
3173         }
3174         assertTrue("Package signatures did not change after upgrade!",
3175                 sigsAfter.contains(sigBefore));
3176         cleanUpInstall(pkgName);
3177     }
3178 
3179     /*
3180      * Check if an apk gains signature-level permission after changing to the a
3181      * new signature, for which a permission should be granted.
3182      */
testUpgradeSigPermGained()3183     public void testUpgradeSigPermGained() throws Exception {
3184         // install apk which defines permission
3185         installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
3186                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3187         // install apk which uses permission but does not have sig
3188         installFromRawResource("permUse.apk", R.raw.keyset_permuse_sb_ua_ub,
3189                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3190         // verify that package does not have perm before
3191         PackageManager pm = getPm();
3192         String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
3193         String pkgName = "com.android.frameworks.coretests.keysets";
3194         String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
3195         assertFalse("keyset permission granted to app without same signature!",
3196                     pm.checkPermission(permName, pkgName)
3197                     == PackageManager.PERMISSION_GRANTED);
3198         // upgrade to apk with perm signature
3199         installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sa_ua_ub,
3200                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3201                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3202         assertTrue("keyset permission not granted to app after upgrade to same sig",
3203                     pm.checkPermission(permName, pkgName)
3204                     == PackageManager.PERMISSION_GRANTED);
3205         cleanUpInstall(permPkgName);
3206         cleanUpInstall(pkgName);
3207     }
3208 
3209     /*
3210      * Check if an apk loses signature-level permission after changing to the a
3211      * new signature, from one which a permission should be granted.
3212      */
testUpgradeSigPermLost()3213     public void testUpgradeSigPermLost() throws Exception {
3214         // install apk which defines permission
3215         installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
3216                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3217         // install apk which uses permission, signed by same sig
3218         installFromRawResource("permUse.apk", R.raw.keyset_permuse_sa_ua_ub,
3219                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3220         // verify that package does not have perm before
3221         PackageManager pm = getPm();
3222         String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
3223         String pkgName = "com.android.frameworks.coretests.keysets";
3224         String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
3225         assertTrue("keyset permission not granted to app with same sig",
3226                     pm.checkPermission(permName, pkgName)
3227                     == PackageManager.PERMISSION_GRANTED);
3228         // upgrade to apk without perm signature
3229         installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sb_ua_ub,
3230                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
3231                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3232 
3233         assertFalse("keyset permission not revoked from app which upgraded to a "
3234                     + "different signature",
3235                     pm.checkPermission(permName, pkgName)
3236                     == PackageManager.PERMISSION_GRANTED);
3237         cleanUpInstall(permPkgName);
3238         cleanUpInstall(pkgName);
3239     }
3240 
3241     /**
3242      * The following tests are related to testing KeySets-based API
3243      */
3244 
3245     /*
3246      * testGetSigningKeySetNull - ensure getSigningKeySet() returns null on null
3247      * input and when calling a package other than that which made the call.
3248      */
testGetSigningKeySet()3249     public void testGetSigningKeySet() throws Exception {
3250         PackageManager pm = getPm();
3251         String mPkgName = mContext.getPackageName();
3252         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3253         KeySet ks;
3254         try {
3255             ks = pm.getSigningKeySet(null);
3256             assertTrue(false); // should have thrown
3257         } catch (NullPointerException e) {
3258         }
3259         try {
3260             ks = pm.getSigningKeySet("keysets.test.bogus.package");
3261             assertTrue(false); // should have thrown
3262         } catch (IllegalArgumentException e) {
3263         }
3264         final InstallParams ip = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3265                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3266         try {
3267             ks = pm.getSigningKeySet(otherPkgName);
3268             assertTrue(false); // should have thrown
3269         } catch (SecurityException e) {
3270         } finally {
3271             cleanUpInstall(ip);
3272         }
3273         ks = pm.getSigningKeySet(mContext.getPackageName());
3274         assertNotNull(ks);
3275     }
3276 
3277     /*
3278      * testGetKeySetByAlias - same as getSigningKeySet, but for keysets defined
3279      * by this package.
3280      */
testGetKeySetByAlias()3281     public void testGetKeySetByAlias() throws Exception {
3282         PackageManager pm = getPm();
3283         String mPkgName = mContext.getPackageName();
3284         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3285         KeySet ks;
3286         try {
3287             ks = pm.getKeySetByAlias(null, null);
3288             assertTrue(false); // should have thrown
3289         } catch (NullPointerException e) {
3290         }
3291         try {
3292             ks = pm.getKeySetByAlias(null, "keysetBogus");
3293             assertTrue(false); // should have thrown
3294         } catch (NullPointerException e) {
3295         }
3296         try {
3297             ks = pm.getKeySetByAlias("keysets.test.bogus.package", null);
3298             assertTrue(false); // should have thrown
3299         } catch (NullPointerException e) {
3300         }
3301         try {
3302             ks = pm.getKeySetByAlias("keysets.test.bogus.package", "A");
3303             assertTrue(false); // should have thrown
3304         } catch(IllegalArgumentException e) {
3305         }
3306         try {
3307             ks = pm.getKeySetByAlias(mPkgName, "keysetBogus");
3308             assertTrue(false); // should have thrown
3309         } catch(IllegalArgumentException e) {
3310         }
3311 
3312         // make sure we can get a KeySet from our pkg
3313         ks = pm.getKeySetByAlias(mPkgName, "A");
3314         assertNotNull(ks);
3315 
3316         // and another
3317         final InstallParams ip = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3318                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3319         try {
3320             ks = pm.getKeySetByAlias(otherPkgName, "A");
3321             assertNotNull(ks);
3322         } finally {
3323             cleanUpInstall(ip);
3324         }
3325     }
3326 
testIsSignedBy()3327     public void testIsSignedBy() throws Exception {
3328         PackageManager pm = getPm();
3329         String mPkgName = mContext.getPackageName();
3330         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3331         KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
3332         KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
3333 
3334         try {
3335             assertFalse(pm.isSignedBy(null, null));
3336             assertTrue(false); // should have thrown
3337         } catch (NullPointerException e) {
3338         }
3339         try {
3340             assertFalse(pm.isSignedBy(null, mSigningKS));
3341             assertTrue(false); // should have thrown
3342         } catch (NullPointerException e) {
3343         }
3344         try {
3345             assertFalse(pm.isSignedBy(mPkgName, null));
3346             assertTrue(false); // should have thrown
3347         } catch (NullPointerException e) {
3348         }
3349         try {
3350             assertFalse(pm.isSignedBy("keysets.test.bogus.package", mDefinedKS));
3351         } catch(IllegalArgumentException e) {
3352         }
3353         assertFalse(pm.isSignedBy(mPkgName, mDefinedKS));
3354         assertFalse(pm.isSignedBy(mPkgName, new KeySet(new Binder())));
3355         assertTrue(pm.isSignedBy(mPkgName, mSigningKS));
3356 
3357         final InstallParams ip1 = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3358                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3359         try {
3360             assertFalse(pm.isSignedBy(otherPkgName, mDefinedKS));
3361             assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
3362         } finally {
3363             cleanUpInstall(ip1);
3364         }
3365 
3366         final InstallParams ip2 = installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
3367                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3368         try {
3369             assertTrue(pm.isSignedBy(otherPkgName, mDefinedKS));
3370             assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
3371         } finally {
3372             cleanUpInstall(ip2);
3373         }
3374     }
3375 
testIsSignedByExactly()3376     public void testIsSignedByExactly() throws Exception {
3377         PackageManager pm = getPm();
3378         String mPkgName = mContext.getPackageName();
3379         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
3380         KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
3381         KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
3382         try {
3383             assertFalse(pm.isSignedBy(null, null));
3384             assertTrue(false); // should have thrown
3385         } catch (NullPointerException e) {
3386         }
3387         try {
3388             assertFalse(pm.isSignedBy(null, mSigningKS));
3389             assertTrue(false); // should have thrown
3390         } catch (NullPointerException e) {
3391         }
3392         try {
3393             assertFalse(pm.isSignedBy(mPkgName, null));
3394             assertTrue(false); // should have thrown
3395         } catch (NullPointerException e) {
3396         }
3397         try {
3398             assertFalse(pm.isSignedByExactly("keysets.test.bogus.package", mDefinedKS));
3399         } catch(IllegalArgumentException e) {
3400         }
3401         assertFalse(pm.isSignedByExactly(mPkgName, mDefinedKS));
3402         assertFalse(pm.isSignedByExactly(mPkgName, new KeySet(new Binder())));
3403         assertTrue(pm.isSignedByExactly(mPkgName, mSigningKS));
3404 
3405         final InstallParams ip1 = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
3406                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3407         try {
3408             assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
3409             assertTrue(pm.isSignedByExactly(otherPkgName, mSigningKS));
3410         } finally {
3411             cleanUpInstall(ip1);
3412         }
3413 
3414         final InstallParams ip2 = installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
3415                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3416         try {
3417             assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
3418             assertFalse(pm.isSignedByExactly(otherPkgName, mSigningKS));
3419         } finally {
3420             cleanUpInstall(ip2);
3421         }
3422     }
3423 
3424 
3425 
3426     /**
3427      * The following tests are related to testing the checkSignatures api.
3428      */
checkSignatures(int apk1, int apk2, int expMatchResult)3429     private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception {
3430         checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
3431     }
3432 
3433     @LargeTest
testCheckSignaturesAllMatch()3434     public void testCheckSignaturesAllMatch() throws Exception {
3435         int apk1 = APP1_CERT1_CERT2;
3436         int apk2 = APP2_CERT1_CERT2;
3437         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3438     }
3439 
3440     @LargeTest
testCheckSignaturesNoMatch()3441     public void testCheckSignaturesNoMatch() throws Exception {
3442         int apk1 = APP1_CERT1;
3443         int apk2 = APP2_CERT2;
3444         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3445     }
3446 
3447     @LargeTest
testCheckSignaturesSomeMatch1()3448     public void testCheckSignaturesSomeMatch1() throws Exception {
3449         int apk1 = APP1_CERT1_CERT2;
3450         int apk2 = APP2_CERT1;
3451         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3452     }
3453 
3454     @LargeTest
testCheckSignaturesSomeMatch2()3455     public void testCheckSignaturesSomeMatch2() throws Exception {
3456         int apk1 = APP1_CERT1_CERT2;
3457         int apk2 = APP2_CERT2;
3458         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3459     }
3460 
3461     @LargeTest
testCheckSignaturesMoreMatch()3462     public void testCheckSignaturesMoreMatch() throws Exception {
3463         int apk1 = APP1_CERT1;
3464         int apk2 = APP2_CERT1_CERT2;
3465         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
3466     }
3467 
3468     @LargeTest
testCheckSignaturesUnknown()3469     public void testCheckSignaturesUnknown() throws Exception {
3470         int apk1 = APP1_CERT1_CERT2;
3471         int apk2 = APP2_CERT1_CERT2;
3472         String apk1Name = "install1.apk";
3473         String apk2Name = "install2.apk";
3474 
3475         final InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
3476                 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3477         try {
3478             PackageManager pm = mContext.getPackageManager();
3479             // Delete app2
3480             File filesDir = mContext.getFilesDir();
3481             File outFile = new File(filesDir, apk2Name);
3482             int rawResId = apk2;
3483             Uri packageURI = getInstallablePackage(rawResId, outFile);
3484             PackageParser.Package pkg = parsePackage(packageURI);
3485             getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
3486             // Check signatures now
3487             int match = mContext.getPackageManager().checkSignatures(
3488                     ip.pkg.packageName, pkg.packageName);
3489             assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3490         } finally {
3491             cleanUpInstall(ip);
3492         }
3493     }
3494 
3495     @LargeTest
testInstallNoCertificates()3496     public void testInstallNoCertificates() throws Exception {
3497         int apk1 = APP1_UNSIGNED;
3498         String apk1Name = "install1.apk";
3499 
3500         installFromRawResource(apk1Name, apk1, 0, false,
3501                 true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
3502                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3503     }
3504 
3505     /*
3506      * The following tests are related to apps using shared uids signed with
3507      * different certs.
3508      */
3509     private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
3510 
3511     private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
3512 
3513     private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
3514 
3515     private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
3516 
3517     private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
3518 
3519     private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
3520 
3521     private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
3522 
3523     private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
3524 
checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult)3525     private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail,
3526             int retCode, int expMatchResult) throws Exception {
3527         String apk1Name = "install1.apk";
3528         String apk2Name = "install2.apk";
3529         PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
3530         PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
3531 
3532         try {
3533             // Clean up before testing first.
3534             cleanUpInstall(pkg1.packageName);
3535             cleanUpInstall(pkg2.packageName);
3536             installFromRawResource(apk1Name, apk1, 0, false, false, -1,
3537                     PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3538             if (fail) {
3539                 installFromRawResource(apk2Name, apk2, 0, false, true, retCode,
3540                         PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3541             } else {
3542                 installFromRawResource(apk2Name, apk2, 0, false, false, -1,
3543                         PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3544                 int match = mContext.getPackageManager().checkSignatures(pkg1.packageName,
3545                         pkg2.packageName);
3546                 assertEquals(expMatchResult, match);
3547             }
3548         } finally {
3549             if (cleanUp) {
3550                 cleanUpInstall(pkg1.packageName);
3551                 cleanUpInstall(pkg2.packageName);
3552             }
3553         }
3554     }
3555 
3556     @LargeTest
testCheckSignaturesSharedAllMatch()3557     public void testCheckSignaturesSharedAllMatch() throws Exception {
3558         int apk1 = SHARED1_CERT1_CERT2;
3559         int apk2 = SHARED2_CERT1_CERT2;
3560         boolean fail = false;
3561         int retCode = -1;
3562         int expMatchResult = PackageManager.SIGNATURE_MATCH;
3563         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3564     }
3565 
3566     @LargeTest
testCheckSignaturesSharedNoMatch()3567     public void testCheckSignaturesSharedNoMatch() throws Exception {
3568         int apk1 = SHARED1_CERT1;
3569         int apk2 = SHARED2_CERT2;
3570         boolean fail = true;
3571         int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3572         int expMatchResult = -1;
3573         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3574     }
3575 
3576     /*
3577      * Test that an app signed with cert1 and cert2 cannot be replaced when
3578      * signed with cert1 alone.
3579      */
3580     @LargeTest
testCheckSignaturesSharedSomeMatch1()3581     public void testCheckSignaturesSharedSomeMatch1() throws Exception {
3582         int apk1 = SHARED1_CERT1_CERT2;
3583         int apk2 = SHARED2_CERT1;
3584         boolean fail = true;
3585         int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3586         int expMatchResult = -1;
3587         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3588     }
3589 
3590     /*
3591      * Test that an app signed with cert1 and cert2 cannot be replaced when
3592      * signed with cert2 alone.
3593      */
3594     @LargeTest
testCheckSignaturesSharedSomeMatch2()3595     public void testCheckSignaturesSharedSomeMatch2() throws Exception {
3596         int apk1 = SHARED1_CERT1_CERT2;
3597         int apk2 = SHARED2_CERT2;
3598         boolean fail = true;
3599         int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3600         int expMatchResult = -1;
3601         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
3602     }
3603 
3604     @LargeTest
testCheckSignaturesSharedUnknown()3605     public void testCheckSignaturesSharedUnknown() throws Exception {
3606         int apk1 = SHARED1_CERT1_CERT2;
3607         int apk2 = SHARED2_CERT1_CERT2;
3608         String apk1Name = "install1.apk";
3609         String apk2Name = "install2.apk";
3610         InstallParams ip1 = null;
3611 
3612         try {
3613             ip1 = installFromRawResource(apk1Name, apk1, 0, false,
3614                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3615             PackageManager pm = mContext.getPackageManager();
3616             // Delete app2
3617             PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
3618             getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
3619             // Check signatures now
3620             int match = mContext.getPackageManager().checkSignatures(
3621                     ip1.pkg.packageName, pkg.packageName);
3622             assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
3623         } finally {
3624             if (ip1 != null) {
3625                 cleanUpInstall(ip1);
3626             }
3627         }
3628     }
3629 
3630     @LargeTest
testReplaceFirstSharedMatchAllCerts()3631     public void testReplaceFirstSharedMatchAllCerts() throws Exception {
3632         int apk1 = SHARED1_CERT1;
3633         int apk2 = SHARED2_CERT1;
3634         int rapk1 = SHARED1_CERT1;
3635         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3636         replaceCerts(apk1, rapk1, true, false, -1);
3637     }
3638 
3639     @LargeTest
testReplaceSecondSharedMatchAllCerts()3640     public void testReplaceSecondSharedMatchAllCerts() throws Exception {
3641         int apk1 = SHARED1_CERT1;
3642         int apk2 = SHARED2_CERT1;
3643         int rapk2 = SHARED2_CERT1;
3644         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
3645         replaceCerts(apk2, rapk2, true, false, -1);
3646     }
3647 
3648     @LargeTest
testReplaceFirstSharedMatchSomeCerts()3649     public void testReplaceFirstSharedMatchSomeCerts() throws Exception {
3650         int apk1 = SHARED1_CERT1_CERT2;
3651         int apk2 = SHARED2_CERT1_CERT2;
3652         int rapk1 = SHARED1_CERT1;
3653         boolean fail = true;
3654         int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3655         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3656         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3657                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3658     }
3659 
3660     @LargeTest
testReplaceSecondSharedMatchSomeCerts()3661     public void testReplaceSecondSharedMatchSomeCerts() throws Exception {
3662         int apk1 = SHARED1_CERT1_CERT2;
3663         int apk2 = SHARED2_CERT1_CERT2;
3664         int rapk2 = SHARED2_CERT1;
3665         boolean fail = true;
3666         int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3667         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3668         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3669                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3670     }
3671 
3672     @LargeTest
testReplaceFirstSharedMatchNoCerts()3673     public void testReplaceFirstSharedMatchNoCerts() throws Exception {
3674         int apk1 = SHARED1_CERT1;
3675         int apk2 = SHARED2_CERT1;
3676         int rapk1 = SHARED1_CERT2;
3677         boolean fail = true;
3678         int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3679         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3680         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3681                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3682     }
3683 
3684     @LargeTest
testReplaceSecondSharedMatchNoCerts()3685     public void testReplaceSecondSharedMatchNoCerts() throws Exception {
3686         int apk1 = SHARED1_CERT1;
3687         int apk2 = SHARED2_CERT1;
3688         int rapk2 = SHARED2_CERT2;
3689         boolean fail = true;
3690         int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3691         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3692         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3693                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3694     }
3695 
3696     @LargeTest
testReplaceFirstSharedMatchMoreCerts()3697     public void testReplaceFirstSharedMatchMoreCerts() throws Exception {
3698         int apk1 = SHARED1_CERT1;
3699         int apk2 = SHARED2_CERT1;
3700         int rapk1 = SHARED1_CERT1_CERT2;
3701         boolean fail = true;
3702         int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3703         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3704         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
3705                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3706     }
3707 
3708     @LargeTest
testReplaceSecondSharedMatchMoreCerts()3709     public void testReplaceSecondSharedMatchMoreCerts() throws Exception {
3710         int apk1 = SHARED1_CERT1;
3711         int apk2 = SHARED2_CERT1;
3712         int rapk2 = SHARED2_CERT1_CERT2;
3713         boolean fail = true;
3714         int retCode = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3715         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
3716         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
3717                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3718     }
3719 
3720     /**
3721      * Unknown features should be allowed to install. This prevents older phones
3722      * from rejecting new packages that specify features that didn't exist when
3723      * an older phone existed. All older phones are assumed to have those
3724      * features.
3725      * <p>
3726      * Right now we allow all packages to be installed regardless of their
3727      * features.
3728      */
3729     @LargeTest
testUsesFeatureUnknownFeature()3730     public void testUsesFeatureUnknownFeature() throws Exception {
3731         int retCode = PackageManager.INSTALL_SUCCEEDED;
3732         installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, false, retCode,
3733                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3734     }
3735 
3736     @LargeTest
testInstallNonexistentFile()3737     public void testInstallNonexistentFile() throws Exception {
3738         int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
3739         File invalidFile = new File("/nonexistent-file.apk");
3740         invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
3741     }
3742 
3743     @SmallTest
testGetVerifierDeviceIdentity()3744     public void testGetVerifierDeviceIdentity() throws Exception {
3745         PackageManager pm = getPm();
3746         VerifierDeviceIdentity id = pm.getVerifierDeviceIdentity();
3747 
3748         assertNotNull("Verifier device identity should not be null", id);
3749     }
3750 
testGetInstalledPackages()3751     public void testGetInstalledPackages() throws Exception {
3752         List<PackageInfo> packages = getPm().getInstalledPackages(0);
3753         assertNotNull("installed packages cannot be null", packages);
3754         assertTrue("installed packages cannot be empty", packages.size() > 0);
3755     }
3756 
testGetUnInstalledPackages()3757     public void testGetUnInstalledPackages() throws Exception {
3758         List<PackageInfo> packages = getPm().getInstalledPackages(
3759                 PackageManager.GET_UNINSTALLED_PACKAGES);
3760         assertNotNull("installed packages cannot be null", packages);
3761         assertTrue("installed packages cannot be empty", packages.size() > 0);
3762     }
3763 
3764     /**
3765      * Test that getInstalledPackages returns all the data specified in flags.
3766      */
testGetInstalledPackagesAll()3767     public void testGetInstalledPackagesAll() throws Exception {
3768         final int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
3769                 | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
3770                 | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
3771                 | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
3772                 | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
3773 
3774         final InstallParams ip =
3775                 installFromRawResource("install.apk", R.raw.install_complete_package_info,
3776                         0 /*flags*/, false /*cleanUp*/, false /*fail*/, -1 /*result*/,
3777                         PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
3778         try {
3779             final List<PackageInfo> packages = getPm().getInstalledPackages(flags);
3780             assertNotNull("installed packages cannot be null", packages);
3781             assertTrue("installed packages cannot be empty", packages.size() > 0);
3782 
3783             PackageInfo packageInfo = null;
3784 
3785             // Find the package with all components specified in the AndroidManifest
3786             // to ensure no null values
3787             for (PackageInfo pi : packages) {
3788                 if ("com.android.frameworks.coretests.install_complete_package_info"
3789                         .equals(pi.packageName)) {
3790                     packageInfo = pi;
3791                     break;
3792                 }
3793             }
3794             assertNotNull("activities should not be null", packageInfo.activities);
3795             assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
3796             assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
3797             assertNotNull("permissions should not be null", packageInfo.permissions);
3798             assertNotNull("providers should not be null", packageInfo.providers);
3799             assertNotNull("receivers should not be null", packageInfo.receivers);
3800             assertNotNull("services should not be null", packageInfo.services);
3801             assertNotNull("signatures should not be null", packageInfo.signatures);
3802         } finally {
3803             cleanUpInstall(ip);
3804         }
3805     }
3806 
3807     /**
3808      * Test that getInstalledPackages returns all the data specified in
3809      * flags when the GET_UNINSTALLED_PACKAGES flag is set.
3810      */
testGetUnInstalledPackagesAll()3811     public void testGetUnInstalledPackagesAll() throws Exception {
3812         final int flags = PackageManager.GET_UNINSTALLED_PACKAGES
3813                 | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
3814                 | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
3815                 | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
3816                 | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
3817                 | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
3818 
3819         // first, install the package
3820         final InstallParams ip =
3821                 installFromRawResource("install.apk", R.raw.install_complete_package_info,
3822                         0 /*flags*/, false /*cleanUp*/, false /*fail*/, -1 /*result*/,
3823                         PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
3824         try {
3825             // then, remove it, keeping it's data around
3826             final GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
3827             invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
3828 
3829             final List<PackageInfo> packages = getPm().getInstalledPackages(flags);
3830             assertNotNull("installed packages cannot be null", packages);
3831             assertTrue("installed packages cannot be empty", packages.size() > 0);
3832 
3833             PackageInfo packageInfo = null;
3834 
3835             // Find the package with all components specified in the AndroidManifest
3836             // to ensure no null values
3837             for (PackageInfo pi : packages) {
3838                 if ("com.android.frameworks.coretests.install_complete_package_info"
3839                         .equals(pi.packageName)) {
3840                     packageInfo = pi;
3841                     break;
3842                 }
3843             }
3844             assertNotNull("activities should not be null", packageInfo.activities);
3845             assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
3846             assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
3847             assertNotNull("permissions should not be null", packageInfo.permissions);
3848             assertNotNull("providers should not be null", packageInfo.providers);
3849             assertNotNull("receivers should not be null", packageInfo.receivers);
3850             assertNotNull("services should not be null", packageInfo.services);
3851             assertNotNull("signatures should not be null", packageInfo.signatures);
3852         } finally {
3853             cleanUpInstall(ip);
3854         }
3855     }
3856 
3857     @Suppress
testInstall_BadDex_CleanUp()3858     public void testInstall_BadDex_CleanUp() throws Exception {
3859         int retCode = PackageManager.INSTALL_FAILED_DEXOPT;
3860         installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode,
3861                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
3862     }
3863 
3864     /*---------- Recommended install location tests ----*/
3865     /*
3866      * TODO's
3867      * check version numbers for upgrades
3868      * check permissions of installed packages
3869      * how to do tests on updated system apps?
3870      * verify updates to system apps cannot be installed on the sdcard.
3871      */
3872 }
3873