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.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.IIntentReceiver;
31 import android.content.IIntentSender;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.content.IntentSender;
35 import android.content.pm.PackageInstaller.SessionParams;
36 import android.content.pm.PackageManager.NameNotFoundException;
37 import android.content.pm.PackageParser.PackageParserException;
38 import android.content.res.Resources;
39 import android.content.res.Resources.NotFoundException;
40 import android.net.Uri;
41 import android.os.Binder;
42 import android.os.Build;
43 import android.os.Bundle;
44 import android.os.Environment;
45 import android.os.FileUtils;
46 import android.os.IBinder;
47 import android.os.Process;
48 import android.os.RemoteException;
49 import android.os.StatFs;
50 import android.os.SystemClock;
51 import android.provider.Settings;
52 import android.provider.Settings.SettingNotFoundException;
53 import android.system.ErrnoException;
54 import android.system.Os;
55 import android.system.StructStat;
56 import android.test.AndroidTestCase;
57 import android.util.Log;
58 
59 import androidx.test.filters.LargeTest;
60 import androidx.test.filters.SmallTest;
61 import androidx.test.filters.Suppress;
62 
63 import com.android.frameworks.coretests.R;
64 import com.android.internal.content.PackageHelper;
65 
66 import dalvik.system.VMRuntime;
67 
68 import libcore.io.IoUtils;
69 
70 import java.io.File;
71 import java.io.FileInputStream;
72 import java.io.IOException;
73 import java.io.InputStream;
74 import java.io.OutputStream;
75 import java.nio.file.Files;
76 import java.nio.file.Paths;
77 import java.nio.file.StandardCopyOption;
78 import java.util.HashSet;
79 import java.util.List;
80 import java.util.Set;
81 import java.util.concurrent.CountDownLatch;
82 import java.util.concurrent.SynchronousQueue;
83 import java.util.concurrent.TimeUnit;
84 
85 public class PackageManagerTests extends AndroidTestCase {
86     private static final boolean localLOGV = true;
87 
88     public static final String TAG = "PackageManagerTests";
89 
90     public static final long MAX_WAIT_TIME = 25 * 1000;
91 
92     public static final long WAIT_TIME_INCR = 5 * 1000;
93 
94     private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
95 
96     private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
97 
98     private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
99 
100     private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL;
101 
failStr(String errMsg)102     void failStr(String errMsg) {
103         Log.w(TAG, "errMsg=" + errMsg);
104         fail(errMsg);
105     }
106 
failStr(Exception e)107     void failStr(Exception e) {
108         failStr(e.getMessage());
109     }
110 
111     private abstract static class GenericReceiver extends BroadcastReceiver {
112         private boolean doneFlag = false;
113 
114         boolean received = false;
115 
116         Intent intent;
117 
118         IntentFilter filter;
119 
notifyNow(Intent intent)120         abstract boolean notifyNow(Intent intent);
121 
122         @Override
onReceive(Context context, Intent intent)123         public void onReceive(Context context, Intent intent) {
124             if (notifyNow(intent)) {
125                 synchronized (this) {
126                     received = true;
127                     doneFlag = true;
128                     this.intent = intent;
129                     notifyAll();
130                 }
131             }
132         }
133 
isDone()134         public boolean isDone() {
135             return doneFlag;
136         }
137 
setFilter(IntentFilter filter)138         public void setFilter(IntentFilter filter) {
139             this.filter = filter;
140         }
141     }
142 
143     private static class InstallReceiver extends GenericReceiver {
144         String pkgName;
145 
InstallReceiver(String pkgName)146         InstallReceiver(String pkgName) {
147             this.pkgName = pkgName;
148             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
149             filter.addDataScheme("package");
150             super.setFilter(filter);
151         }
152 
notifyNow(Intent intent)153         public boolean notifyNow(Intent intent) {
154             String action = intent.getAction();
155             if (!Intent.ACTION_PACKAGE_ADDED.equals(action)) {
156                 return false;
157             }
158             Uri data = intent.getData();
159             String installedPkg = data.getEncodedSchemeSpecificPart();
160             if (pkgName.equals(installedPkg)) {
161                 return true;
162             }
163             return false;
164         }
165     }
166 
167     private static class LocalIntentReceiver {
168         private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
169 
170         private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
171             @Override
172             public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
173                     IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
174                 try {
175                     mResult.offer(intent, 5, TimeUnit.SECONDS);
176                 } catch (InterruptedException e) {
177                     throw new RuntimeException(e);
178                 }
179             }
180         };
181 
getIntentSender()182         public IntentSender getIntentSender() {
183             return new IntentSender((IIntentSender) mLocalSender);
184         }
185 
getResult()186         public Intent getResult() {
187             try {
188                 return mResult.take();
189             } catch (InterruptedException e) {
190                 throw new RuntimeException(e);
191             }
192         }
193     }
194 
getPm()195     private PackageManager getPm() {
196         return mContext.getPackageManager();
197     }
198 
getPi()199     private PackageInstaller getPi() {
200         return getPm().getPackageInstaller();
201     }
202 
writeSplitToInstallSession(PackageInstaller.Session session, String inPath, String splitName)203     private void writeSplitToInstallSession(PackageInstaller.Session session, String inPath,
204             String splitName) throws RemoteException {
205         long sizeBytes = 0;
206         final File file = new File(inPath);
207         if (file.isFile()) {
208             sizeBytes = file.length();
209         } else {
210             return;
211         }
212 
213         InputStream in = null;
214         OutputStream out = null;
215         try {
216             in = new FileInputStream(inPath);
217             out = session.openWrite(splitName, 0, sizeBytes);
218 
219             int total = 0;
220             byte[] buffer = new byte[65536];
221             int c;
222             while ((c = in.read(buffer)) != -1) {
223                 total += c;
224                 out.write(buffer, 0, c);
225             }
226             session.fsync(out);
227         } catch (IOException e) {
228             fail("Error: failed to write; " + e.getMessage());
229         } finally {
230             IoUtils.closeQuietly(out);
231             IoUtils.closeQuietly(in);
232             IoUtils.closeQuietly(session);
233         }
234     }
235 
invokeInstallPackage(Uri packageUri, int flags, GenericReceiver receiver, boolean shouldSucceed)236     private void invokeInstallPackage(Uri packageUri, int flags, GenericReceiver receiver,
237             boolean shouldSucceed) {
238         mContext.registerReceiver(receiver, receiver.filter);
239         synchronized (receiver) {
240             final String inPath = packageUri.getPath();
241             PackageInstaller.Session session = null;
242             try {
243                 final SessionParams sessionParams =
244                         new SessionParams(SessionParams.MODE_FULL_INSTALL);
245                 sessionParams.installFlags = flags;
246                 final int sessionId = getPi().createSession(sessionParams);
247                 session = getPi().openSession(sessionId);
248                 writeSplitToInstallSession(session, inPath, "base.apk");
249                 final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
250                 session.commit(localReceiver.getIntentSender());
251                 final Intent result = localReceiver.getResult();
252                 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
253                         PackageInstaller.STATUS_FAILURE);
254                 if (shouldSucceed) {
255                     if (status != PackageInstaller.STATUS_SUCCESS) {
256                         fail("Installation should have succeeded, but got code " + status);
257                     }
258                 } else {
259                     if (status == PackageInstaller.STATUS_SUCCESS) {
260                         fail("Installation should have failed");
261                     }
262                     // We'll never get a broadcast since the package failed to install
263                     return;
264                 }
265                 // Verify we received the broadcast
266                 long waitTime = 0;
267                 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
268                     try {
269                         receiver.wait(WAIT_TIME_INCR);
270                         waitTime += WAIT_TIME_INCR;
271                     } catch (InterruptedException e) {
272                         Log.i(TAG, "Interrupted during sleep", e);
273                     }
274                 }
275                 if (!receiver.isDone()) {
276                     fail("Timed out waiting for PACKAGE_ADDED notification");
277                 }
278             } catch (IllegalArgumentException | IOException | RemoteException e) {
279                 Log.w(TAG, "Failed to install package; path=" + inPath, e);
280                 fail("Failed to install package; path=" + inPath + ", e=" + e);
281             } finally {
282                 IoUtils.closeQuietly(session);
283                 mContext.unregisterReceiver(receiver);
284             }
285         }
286     }
287 
invokeInstallPackageFail(Uri packageUri, int flags, int expectedResult)288     private void invokeInstallPackageFail(Uri packageUri, int flags, int expectedResult) {
289         final String inPath = packageUri.getPath();
290         PackageInstaller.Session session = null;
291         try {
292             final SessionParams sessionParams =
293                     new SessionParams(SessionParams.MODE_FULL_INSTALL);
294             sessionParams.installFlags = flags;
295             final int sessionId = getPi().createSession(sessionParams);
296             session = getPi().openSession(sessionId);
297             writeSplitToInstallSession(session, inPath, "base.apk");
298             final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
299             session.commit(localReceiver.getIntentSender());
300             final Intent result = localReceiver.getResult();
301             final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
302                     PackageInstaller.STATUS_SUCCESS);
303             assertEquals(expectedResult, status);
304         } catch (IllegalArgumentException | IOException | RemoteException e) {
305             Log.w(TAG, "Failed to install package; path=" + inPath, e);
306             fail("Failed to install package; path=" + inPath + ", e=" + e);
307         } finally {
308             IoUtils.closeQuietly(session);
309         }
310     }
311 
getInstallablePackage(int fileResId, File outFile)312     private Uri getInstallablePackage(int fileResId, File outFile) {
313         Resources res = mContext.getResources();
314         InputStream is = null;
315         try {
316             is = res.openRawResource(fileResId);
317         } catch (NotFoundException e) {
318             failStr("Failed to load resource with id: " + fileResId);
319         }
320         FileUtils.setPermissions(outFile.getPath(),
321                 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
322                 -1, -1);
323         assertTrue(FileUtils.copyToFile(is, outFile));
324         FileUtils.setPermissions(outFile.getPath(),
325                 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO,
326                 -1, -1);
327         return Uri.fromFile(outFile);
328     }
329 
parsePackage(Uri packageURI)330     private PackageParser.Package parsePackage(Uri packageURI) throws PackageParserException {
331         final String archiveFilePath = packageURI.getPath();
332         PackageParser packageParser = new PackageParser();
333         File sourceFile = new File(archiveFilePath);
334         PackageParser.Package pkg = packageParser.parseMonolithicPackage(sourceFile, 0);
335         packageParser = null;
336         return pkg;
337     }
338 
checkSd(long pkgLen)339     private boolean checkSd(long pkgLen) {
340         String status = Environment.getExternalStorageState();
341         if (!status.equals(Environment.MEDIA_MOUNTED)) {
342             return false;
343         }
344         long sdSize = -1;
345         StatFs sdStats = new StatFs(Environment.getExternalStorageDirectory().getPath());
346         sdSize = (long) sdStats.getAvailableBlocks() * (long) sdStats.getBlockSize();
347         // TODO check for thresholds here
348         return pkgLen <= sdSize;
349 
350     }
351 
checkInt(long pkgLen)352     private boolean checkInt(long pkgLen) {
353         StatFs intStats = new StatFs(Environment.getDataDirectory().getPath());
354         long intSize = (long) intStats.getBlockCount() * (long) intStats.getBlockSize();
355         long iSize = (long) intStats.getAvailableBlocks() * (long) intStats.getBlockSize();
356         // TODO check for thresholds here?
357         return pkgLen <= iSize;
358     }
359 
360     private static final int INSTALL_LOC_INT = 1;
361 
362     private static final int INSTALL_LOC_SD = 2;
363 
364     private static final int INSTALL_LOC_ERR = -1;
365 
getInstallLoc(int flags, int expInstallLocation, long pkgLen)366     private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) {
367         // Flags explicitly over ride everything else.
368         if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
369             return INSTALL_LOC_INT;
370         }
371         // Manifest option takes precedence next
372         if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
373             if (checkSd(pkgLen)) {
374                 return INSTALL_LOC_SD;
375             }
376             if (checkInt(pkgLen)) {
377                 return INSTALL_LOC_INT;
378             }
379             return INSTALL_LOC_ERR;
380         }
381         if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
382             if (checkInt(pkgLen)) {
383                 return INSTALL_LOC_INT;
384             }
385             return INSTALL_LOC_ERR;
386         }
387         if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
388             // Check for free memory internally
389             if (checkInt(pkgLen)) {
390                 return INSTALL_LOC_INT;
391             }
392             // Check for free memory externally
393             if (checkSd(pkgLen)) {
394                 return INSTALL_LOC_SD;
395             }
396             return INSTALL_LOC_ERR;
397         }
398         // Check for settings preference.
399         boolean checkSd = false;
400         int userPref = getDefaultInstallLoc();
401         if (userPref == APP_INSTALL_DEVICE) {
402             if (checkInt(pkgLen)) {
403                 return INSTALL_LOC_INT;
404             }
405             return INSTALL_LOC_ERR;
406         } else if (userPref == APP_INSTALL_SDCARD) {
407             if (checkSd(pkgLen)) {
408                 return INSTALL_LOC_SD;
409             }
410             return INSTALL_LOC_ERR;
411         }
412         // Default system policy for apps with no manifest option specified.
413         // Check for free memory internally
414         if (checkInt(pkgLen)) {
415             return INSTALL_LOC_INT;
416         }
417         return INSTALL_LOC_ERR;
418     }
419 
assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation)420     private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
421         try {
422             String pkgName = pkg.packageName;
423             ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
424             assertNotNull(info);
425             assertEquals(pkgName, info.packageName);
426             File dataDir = Environment.getDataDirectory();
427             String appInstallPath = new File(dataDir, "app").getPath();
428             String drmInstallPath = new File(dataDir, "app-private").getPath();
429             File srcDir = new File(info.sourceDir);
430             String srcPath = srcDir.getParentFile().getParent();
431             File publicSrcDir = new File(info.publicSourceDir);
432             String publicSrcPath = publicSrcDir.getParentFile().getParent();
433             long pkgLen = new File(info.sourceDir).length();
434             String expectedLibPath = new File(new File(info.sourceDir).getParentFile(), "lib")
435                     .getPath();
436 
437             int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
438             if (rLoc == INSTALL_LOC_INT) {
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                 assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
449 
450                 // Make sure the native library dir is not a symlink
451                 final File nativeLibDir = new File(info.nativeLibraryDir);
452                 if (nativeLibDir.exists()) {
453                     try {
454                         assertEquals("Native library dir should not be a symlink",
455                                 info.nativeLibraryDir, nativeLibDir.getCanonicalPath());
456                     } catch (IOException e) {
457                         fail("Can't read " + nativeLibDir.getPath());
458                     }
459                 }
460             } else if (rLoc == INSTALL_LOC_SD) {
461                 assertTrue("Application flags (" + info.flags
462                         + ") should contain FLAG_EXTERNAL_STORAGE",
463                         (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
464                 // Might need to check:
465                 // ((info.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) != 0)
466                 assertStartsWith("The APK path should point to the ASEC",
467                         SECURE_CONTAINERS_PREFIX, srcPath);
468                 assertStartsWith("The public APK path should point to the ASEC",
469                         SECURE_CONTAINERS_PREFIX, publicSrcPath);
470                 assertStartsWith("The native library path should point to the ASEC",
471                         SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
472 
473                 // Make sure the native library in /data/data/<app>/lib is a
474                 // symlink to the ASEC
475                 final File nativeLibSymLink = new File(info.dataDir, "lib");
476                 assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(),
477                         nativeLibSymLink.exists());
478                 try {
479                     assertEquals(nativeLibSymLink.getPath() + " should be a symlink to "
480                             + info.nativeLibraryDir, info.nativeLibraryDir,
481                             nativeLibSymLink.getCanonicalPath());
482                 } catch (IOException e) {
483                     fail("Can't read " + nativeLibSymLink.getPath());
484                 }
485             } else {
486                 // TODO handle error. Install should have failed.
487                 fail("Install should have failed");
488             }
489         } catch (NameNotFoundException e) {
490             failStr("failed with exception : " + e);
491         }
492     }
493 
assertDirOwnerGroupPermsIfExists(String reason, int uid, int gid, int perms, String path)494     private void assertDirOwnerGroupPermsIfExists(String reason, int uid, int gid, int perms,
495             String path) {
496         if (!new File(path).exists()) {
497             return;
498         }
499 
500         final StructStat stat;
501         try {
502             stat = Os.lstat(path);
503         } catch (ErrnoException e) {
504             throw new AssertionError(reason + "\n" + "Got: " + path + " does not exist");
505         }
506 
507         StringBuilder sb = new StringBuilder();
508 
509         if (!S_ISDIR(stat.st_mode)) {
510             sb.append("\nExpected type: ");
511             sb.append(S_IFDIR);
512             sb.append("\ngot type: ");
513             sb.append((stat.st_mode & S_IFMT));
514         }
515 
516         if (stat.st_uid != uid) {
517             sb.append("\nExpected owner: ");
518             sb.append(uid);
519             sb.append("\nGot owner: ");
520             sb.append(stat.st_uid);
521         }
522 
523         if (stat.st_gid != gid) {
524             sb.append("\nExpected group: ");
525             sb.append(gid);
526             sb.append("\nGot group: ");
527             sb.append(stat.st_gid);
528         }
529 
530         if ((stat.st_mode & ~S_IFMT) != perms) {
531             sb.append("\nExpected permissions: ");
532             sb.append(Integer.toOctalString(perms));
533             sb.append("\nGot permissions: ");
534             sb.append(Integer.toOctalString(stat.st_mode & ~S_IFMT));
535         }
536 
537         if (sb.length() > 0) {
538             throw new AssertionError(reason + sb.toString());
539         }
540     }
541 
assertStartsWith(String prefix, String actual)542     private static void assertStartsWith(String prefix, String actual) {
543         assertStartsWith("", prefix, actual);
544     }
545 
assertStartsWith(String description, String prefix, String actual)546     private static void assertStartsWith(String description, String prefix, String actual) {
547         if (!actual.startsWith(prefix)) {
548             StringBuilder sb = new StringBuilder(description);
549             sb.append("\nExpected prefix: ");
550             sb.append(prefix);
551             sb.append("\n     got: ");
552             sb.append(actual);
553             sb.append('\n');
554             throw new AssertionError(sb.toString());
555         }
556     }
557 
assertNotInstalled(String pkgName)558     private void assertNotInstalled(String pkgName) {
559         try {
560             ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
561             fail(pkgName + " shouldnt be installed");
562         } catch (NameNotFoundException e) {
563         }
564     }
565 
566     class InstallParams {
567         Uri packageURI;
568 
569         PackageParser.Package pkg;
570 
InstallParams(String outFileName, int rawResId)571         InstallParams(String outFileName, int rawResId) throws PackageParserException {
572             this.pkg = getParsedPackage(outFileName, rawResId);
573             this.packageURI = Uri.fromFile(new File(pkg.codePath));
574         }
575 
InstallParams(PackageParser.Package pkg)576         InstallParams(PackageParser.Package pkg) {
577             this.packageURI = Uri.fromFile(new File(pkg.codePath));
578             this.pkg = pkg;
579         }
580 
getApkSize()581         long getApkSize() {
582             File file = new File(pkg.codePath);
583             return file.length();
584         }
585     }
586 
sampleInstallFromRawResource(int flags, boolean cleanUp)587     private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp)
588             throws Exception {
589         return installFromRawResource("install.apk", R.raw.install, flags, cleanUp, false, -1,
590                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
591     }
592 
593     static final String PERM_PACKAGE = "package";
594 
595     static final String PERM_DEFINED = "defined";
596 
597     static final String PERM_UNDEFINED = "undefined";
598 
599     static final String PERM_USED = "used";
600 
601     static final String PERM_NOTUSED = "notused";
602 
assertPermissions(String[] cmds)603     private void assertPermissions(String[] cmds) {
604         final PackageManager pm = getPm();
605         String pkg = null;
606         PackageInfo pkgInfo = null;
607         String mode = PERM_DEFINED;
608         int i = 0;
609         while (i < cmds.length) {
610             String cmd = cmds[i++];
611             if (cmd == PERM_PACKAGE) {
612                 pkg = cmds[i++];
613                 try {
614                     pkgInfo = pm.getPackageInfo(pkg,
615                             PackageManager.GET_PERMISSIONS
616                             | PackageManager.MATCH_UNINSTALLED_PACKAGES);
617                 } catch (NameNotFoundException e) {
618                     pkgInfo = null;
619                 }
620             } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED
621                     || cmd == PERM_USED || cmd == PERM_NOTUSED) {
622                 mode = cmds[i++];
623             } else {
624                 if (mode == PERM_DEFINED) {
625                     try {
626                         PermissionInfo pi = pm.getPermissionInfo(cmd, 0);
627                         assertNotNull(pi);
628                         assertEquals(pi.packageName, pkg);
629                         assertEquals(pi.name, cmd);
630                         assertNotNull(pkgInfo);
631                         boolean found = false;
632                         for (int j = 0; j < pkgInfo.permissions.length && !found; j++) {
633                             if (pkgInfo.permissions[j].name.equals(cmd)) {
634                                 found = true;
635                             }
636                         }
637                         if (!found) {
638                             fail("Permission not found: " + cmd);
639                         }
640                     } catch (NameNotFoundException e) {
641                         throw new RuntimeException(e);
642                     }
643                 } else if (mode == PERM_UNDEFINED) {
644                     try {
645                         pm.getPermissionInfo(cmd, 0);
646                         throw new RuntimeException("Permission exists: " + cmd);
647                     } catch (NameNotFoundException e) {
648                     }
649                     if (pkgInfo != null) {
650                         boolean found = false;
651                         for (int j = 0; j < pkgInfo.permissions.length && !found; j++) {
652                             if (pkgInfo.permissions[j].name.equals(cmd)) {
653                                 found = true;
654                             }
655                         }
656                         if (found) {
657                             fail("Permission still exists: " + cmd);
658                         }
659                     }
660                 } else if (mode == PERM_USED || mode == PERM_NOTUSED) {
661                     boolean found = false;
662                     for (int j = 0; j < pkgInfo.requestedPermissions.length && !found; j++) {
663                         if (pkgInfo.requestedPermissions[j].equals(cmd)) {
664                             found = true;
665                         }
666                     }
667                     if (!found) {
668                         fail("Permission not requested: " + cmd);
669                     }
670                     if (mode == PERM_USED) {
671                         if (pm.checkPermission(cmd, pkg) != PackageManager.PERMISSION_GRANTED) {
672                             fail("Permission not granted: " + cmd);
673                         }
674                     } else {
675                         if (pm.checkPermission(cmd, pkg) != PackageManager.PERMISSION_DENIED) {
676                             fail("Permission granted: " + cmd);
677                         }
678                     }
679                 }
680             }
681         }
682     }
683 
getParsedPackage(String outFileName, int rawResId)684     private PackageParser.Package getParsedPackage(String outFileName, int rawResId)
685             throws PackageParserException {
686         PackageManager pm = mContext.getPackageManager();
687         File filesDir = mContext.getFilesDir();
688         File outFile = new File(filesDir, outFileName);
689         Uri packageURI = getInstallablePackage(rawResId, outFile);
690         PackageParser.Package pkg = parsePackage(packageURI);
691         return pkg;
692     }
693 
694     /*
695      * Utility function that reads a apk bundled as a raw resource
696      * copies it into own data directory and invokes
697      * PackageManager api to install it.
698      */
installFromRawResource(InstallParams ip, int flags, boolean cleanUp, boolean fail, int result, int expInstallLocation)699     private void installFromRawResource(InstallParams ip, int flags, boolean cleanUp, boolean fail,
700             int result, int expInstallLocation) throws Exception {
701         PackageManager pm = mContext.getPackageManager();
702         PackageParser.Package pkg = ip.pkg;
703         Uri packageURI = ip.packageURI;
704         if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
705             // Make sure the package doesn't exist
706             try {
707                 ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName,
708                         PackageManager.MATCH_UNINSTALLED_PACKAGES);
709                 GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
710                 invokeDeletePackage(pkg.packageName, 0, receiver);
711             } catch (IllegalArgumentException | NameNotFoundException e) {
712             }
713         }
714         try {
715             if (fail) {
716                 invokeInstallPackageFail(packageURI, flags, result);
717                 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
718                     assertNotInstalled(pkg.packageName);
719                 }
720             } else {
721                 InstallReceiver receiver = new InstallReceiver(pkg.packageName);
722                 invokeInstallPackage(packageURI, flags, receiver, true);
723                 // Verify installed information
724                 assertInstall(pkg, flags, expInstallLocation);
725             }
726         } finally {
727             if (cleanUp) {
728                 cleanUpInstall(ip);
729             }
730         }
731     }
732 
733     /*
734      * Utility function that reads a apk bundled as a raw resource
735      * copies it into own data directory and invokes
736      * PackageManager api to install it.
737      */
installFromRawResource(String outFileName, int rawResId, int flags, boolean cleanUp, boolean fail, int result, int expInstallLocation)738     private InstallParams installFromRawResource(String outFileName, int rawResId, int flags,
739             boolean cleanUp, boolean fail, int result, int expInstallLocation) throws Exception {
740         InstallParams ip = new InstallParams(outFileName, rawResId);
741         installFromRawResource(ip, flags, cleanUp, fail, result, expInstallLocation);
742         return ip;
743     }
744 
745     @LargeTest
testInstallNormalInternal()746     public void testInstallNormalInternal() throws Exception {
747         sampleInstallFromRawResource(0, true);
748     }
749 
750     /* ------------------------- Test replacing packages -------------- */
751     class ReplaceReceiver extends GenericReceiver {
752         String pkgName;
753 
754         final static int INVALID = -1;
755 
756         final static int REMOVED = 1;
757 
758         final static int ADDED = 2;
759 
760         final static int REPLACED = 3;
761 
762         int removed = INVALID;
763 
764         // for updated system apps only
765         boolean update = false;
766 
ReplaceReceiver(String pkgName)767         ReplaceReceiver(String pkgName) {
768             this.pkgName = pkgName;
769             filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
770             filter.addAction(Intent.ACTION_PACKAGE_ADDED);
771             if (update) {
772                 filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
773             }
774             filter.addDataScheme("package");
775             super.setFilter(filter);
776         }
777 
notifyNow(Intent intent)778         public boolean notifyNow(Intent intent) {
779             String action = intent.getAction();
780             Uri data = intent.getData();
781             String installedPkg = data.getEncodedSchemeSpecificPart();
782             if (pkgName == null || !pkgName.equals(installedPkg)) {
783                 return false;
784             }
785             if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
786                 removed = REMOVED;
787             } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
788                 if (removed != REMOVED) {
789                     return false;
790                 }
791                 boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
792                 if (!replacing) {
793                     return false;
794                 }
795                 removed = ADDED;
796                 if (!update) {
797                     return true;
798                 }
799             } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
800                 if (removed != ADDED) {
801                     return false;
802                 }
803                 removed = REPLACED;
804                 return true;
805             }
806             return false;
807         }
808     }
809 
810     /*
811      * Utility function that reads a apk bundled as a raw resource
812      * copies it into own data directory and invokes
813      * PackageManager api to install first and then replace it
814      * again.
815      */
sampleReplaceFromRawResource(int flags)816     private void sampleReplaceFromRawResource(int flags) throws Exception {
817         InstallParams ip = sampleInstallFromRawResource(flags, false);
818         boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
819         Log.i(TAG, "replace=" + replace);
820         GenericReceiver receiver;
821         if (replace) {
822             receiver = new ReplaceReceiver(ip.pkg.packageName);
823             Log.i(TAG, "Creating replaceReceiver");
824         } else {
825             receiver = new InstallReceiver(ip.pkg.packageName);
826         }
827         try {
828             invokeInstallPackage(ip.packageURI, flags, receiver, true);
829             if (replace) {
830                 assertInstall(ip.pkg, flags, ip.pkg.installLocation);
831             }
832         } finally {
833             cleanUpInstall(ip);
834         }
835     }
836 
837     @LargeTest
testReplaceFlagDoesNotNeedToBeSet()838     public void testReplaceFlagDoesNotNeedToBeSet() throws Exception {
839         sampleReplaceFromRawResource(0);
840     }
841 
842     @LargeTest
testReplaceNormalInternal()843     public void testReplaceNormalInternal() throws Exception {
844         sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
845     }
846 
847     /* -------------- Delete tests --- */
848     private static class DeleteObserver extends IPackageDeleteObserver.Stub {
849         private CountDownLatch mLatch = new CountDownLatch(1);
850 
851         private int mReturnCode;
852 
853         private final String mPackageName;
854 
855         private String mObservedPackage;
856 
DeleteObserver(String packageName)857         public DeleteObserver(String packageName) {
858             mPackageName = packageName;
859         }
860 
isSuccessful()861         public boolean isSuccessful() {
862             return mReturnCode == PackageManager.DELETE_SUCCEEDED;
863         }
864 
packageDeleted(String packageName, int returnCode)865         public void packageDeleted(String packageName, int returnCode) throws RemoteException {
866             mObservedPackage = packageName;
867 
868             mReturnCode = returnCode;
869 
870             mLatch.countDown();
871         }
872 
waitForCompletion(long timeoutMillis)873         public void waitForCompletion(long timeoutMillis) {
874             final long deadline = SystemClock.uptimeMillis() + timeoutMillis;
875 
876             long waitTime = timeoutMillis;
877             while (waitTime > 0) {
878                 try {
879                     boolean done = mLatch.await(waitTime, TimeUnit.MILLISECONDS);
880                     if (done) {
881                         assertEquals(mPackageName, mObservedPackage);
882                         return;
883                     }
884                 } catch (InterruptedException e) {
885                     // TODO Auto-generated catch block
886                     e.printStackTrace();
887                 }
888                 waitTime = deadline - SystemClock.uptimeMillis();
889             }
890 
891             throw new AssertionError("Timeout waiting for package deletion");
892         }
893     }
894 
895     class DeleteReceiver extends GenericReceiver {
896         String pkgName;
897 
DeleteReceiver(String pkgName)898         DeleteReceiver(String pkgName) {
899             this.pkgName = pkgName;
900             IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
901             filter.addDataScheme("package");
902             super.setFilter(filter);
903         }
904 
notifyNow(Intent intent)905         public boolean notifyNow(Intent intent) {
906             String action = intent.getAction();
907             if (!Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
908                 return false;
909             }
910             Uri data = intent.getData();
911             String installedPkg = data.getEncodedSchemeSpecificPart();
912             if (pkgName.equals(installedPkg)) {
913                 return true;
914             }
915             return false;
916         }
917     }
918 
invokeDeletePackage(final String pkgName, int flags, GenericReceiver receiver)919     public boolean invokeDeletePackage(final String pkgName, int flags, GenericReceiver receiver)
920             throws Exception {
921         ApplicationInfo info = getPm().getApplicationInfo(pkgName,
922                 PackageManager.MATCH_UNINSTALLED_PACKAGES);
923 
924         mContext.registerReceiver(receiver, receiver.filter);
925         try {
926             final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
927             getPi().uninstall(pkgName,
928                     flags | PackageManager.DELETE_ALL_USERS,
929                     localReceiver.getIntentSender());
930             localReceiver.getResult();
931 
932             assertUninstalled(info);
933 
934             // Verify we received the broadcast
935             // TODO replace this with a CountDownLatch
936             synchronized (receiver) {
937                 long waitTime = 0;
938                 while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
939                     receiver.wait(WAIT_TIME_INCR);
940                     waitTime += WAIT_TIME_INCR;
941                 }
942                 if (!receiver.isDone()) {
943                     throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
944                 }
945             }
946             return receiver.received;
947         } finally {
948             mContext.unregisterReceiver(receiver);
949         }
950     }
951 
assertUninstalled(ApplicationInfo info)952     private static void assertUninstalled(ApplicationInfo info) throws Exception {
953         File nativeLibraryFile = new File(info.nativeLibraryDir);
954         assertFalse("Native library directory " + info.nativeLibraryDir
955                 + " should be erased", nativeLibraryFile.exists());
956     }
957 
deleteFromRawResource(int iFlags, int dFlags)958     public void deleteFromRawResource(int iFlags, int dFlags) throws Exception {
959         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
960         boolean retainData = ((dFlags & PackageManager.DELETE_KEEP_DATA) != 0);
961         GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
962         try {
963             assertTrue(invokeDeletePackage(ip.pkg.packageName, dFlags, receiver));
964             ApplicationInfo info = null;
965             Log.i(TAG, "okay4");
966             try {
967                 info = getPm().getApplicationInfo(ip.pkg.packageName,
968                         PackageManager.MATCH_UNINSTALLED_PACKAGES);
969             } catch (NameNotFoundException e) {
970                 info = null;
971             }
972             if (retainData) {
973                 assertNotNull(info);
974                 assertEquals(info.packageName, ip.pkg.packageName);
975                 File file = new File(info.dataDir);
976                 assertTrue(file.exists());
977             } else {
978                 assertNull(info);
979             }
980         } catch (Exception e) {
981             failStr(e);
982         } finally {
983             cleanUpInstall(ip);
984         }
985     }
986 
987     @LargeTest
testDeleteNormalInternal()988     public void testDeleteNormalInternal() throws Exception {
989         deleteFromRawResource(0, 0);
990     }
991 
992 
993     @LargeTest
testDeleteNormalInternalRetainData()994     public void testDeleteNormalInternalRetainData() throws Exception {
995         deleteFromRawResource(0, PackageManager.DELETE_KEEP_DATA);
996     }
997 
cleanUpInstall(InstallParams ip)998     void cleanUpInstall(InstallParams ip) throws Exception {
999         if (ip == null) {
1000             return;
1001         }
1002         Runtime.getRuntime().gc();
1003         try {
1004             cleanUpInstall(ip.pkg.packageName);
1005         } finally {
1006             File outFile = new File(ip.pkg.codePath);
1007             if (outFile != null && outFile.exists()) {
1008                 outFile.delete();
1009             }
1010         }
1011     }
1012 
cleanUpInstall(String pkgName)1013     private void cleanUpInstall(String pkgName) throws Exception {
1014         if (pkgName == null) {
1015             return;
1016         }
1017         Log.i(TAG, "Deleting package : " + pkgName);
1018         try {
1019             final ApplicationInfo info = getPm().getApplicationInfo(pkgName,
1020                     PackageManager.MATCH_UNINSTALLED_PACKAGES);
1021             if (info != null) {
1022                 final LocalIntentReceiver localReceiver = new LocalIntentReceiver();
1023                 getPi().uninstall(pkgName,
1024                         PackageManager.DELETE_ALL_USERS,
1025                         localReceiver.getIntentSender());
1026                 localReceiver.getResult();
1027                 assertUninstalled(info);
1028             }
1029         } catch (IllegalArgumentException | NameNotFoundException e) {
1030         }
1031     }
1032 
1033     @LargeTest
testManifestInstallLocationInternal()1034     public void testManifestInstallLocationInternal() throws Exception {
1035         installFromRawResource("install.apk", R.raw.install_loc_internal,
1036                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1037     }
1038 
1039     @LargeTest
testManifestInstallLocationSdcard()1040     public void testManifestInstallLocationSdcard() throws Exception {
1041         // Do not run on devices with emulated external storage.
1042         if (Environment.isExternalStorageEmulated()) {
1043             return;
1044         }
1045 
1046         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1047                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1048     }
1049 
1050     @LargeTest
testManifestInstallLocationAuto()1051     public void testManifestInstallLocationAuto() throws Exception {
1052         installFromRawResource("install.apk", R.raw.install_loc_auto,
1053                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
1054     }
1055 
1056     @LargeTest
testManifestInstallLocationUnspecified()1057     public void testManifestInstallLocationUnspecified() throws Exception {
1058         installFromRawResource("install.apk", R.raw.install_loc_unspecified,
1059                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1060     }
1061 
1062     @LargeTest
testManifestInstallLocationReplaceInternalSdcard()1063     public void testManifestInstallLocationReplaceInternalSdcard() throws Exception {
1064         // Do not run on devices with emulated external storage.
1065         if (Environment.isExternalStorageEmulated()) {
1066             return;
1067         }
1068 
1069         int iFlags = 0;
1070         int iApk = R.raw.install_loc_internal;
1071         int rFlags = 0;
1072         int rApk = R.raw.install_loc_sdcard;
1073         InstallParams ip = installFromRawResource("install.apk", iApk,
1074                 iFlags, false,
1075                 false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1076         GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
1077         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1078         try {
1079             InstallParams rp = installFromRawResource("install.apk", rApk,
1080                     replaceFlags, false,
1081                     false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1082             assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
1083         } catch (Exception e) {
1084             failStr("Failed with exception : " + e);
1085         } finally {
1086             cleanUpInstall(ip);
1087         }
1088     }
1089 
1090     @LargeTest
testManifestInstallLocationReplaceSdcardInternal()1091     public void testManifestInstallLocationReplaceSdcardInternal() throws Exception {
1092         // Do not run on devices with emulated external storage.
1093         if (Environment.isExternalStorageEmulated()) {
1094             return;
1095         }
1096 
1097         int iFlags = 0;
1098         int iApk = R.raw.install_loc_sdcard;
1099         int rFlags = 0;
1100         int rApk = R.raw.install_loc_unspecified;
1101         InstallParams ip = installFromRawResource("install.apk", iApk,
1102                 iFlags, false,
1103                 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1104         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
1105         try {
1106             InstallParams rp = installFromRawResource("install.apk", rApk,
1107                     replaceFlags, false,
1108                     false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1109             assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
1110         } catch (Exception e) {
1111             failStr("Failed with exception : " + e);
1112         } finally {
1113             cleanUpInstall(ip);
1114         }
1115     }
1116 
1117     class MoveReceiver extends GenericReceiver {
1118         String pkgName;
1119 
1120         final static int INVALID = -1;
1121 
1122         final static int REMOVED = 1;
1123 
1124         final static int ADDED = 2;
1125 
1126         int removed = INVALID;
1127 
MoveReceiver(String pkgName)1128         MoveReceiver(String pkgName) {
1129             this.pkgName = pkgName;
1130             filter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
1131             filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
1132             super.setFilter(filter);
1133         }
1134 
notifyNow(Intent intent)1135         public boolean notifyNow(Intent intent) {
1136             String action = intent.getAction();
1137             Log.i(TAG, "MoveReceiver::" + action);
1138             if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
1139                 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1140                 if (list != null) {
1141                     for (String pkg : list) {
1142                         if (pkg.equals(pkgName)) {
1143                             removed = REMOVED;
1144                             break;
1145                         }
1146                     }
1147                 }
1148                 removed = REMOVED;
1149             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
1150                 if (removed != REMOVED) {
1151                     return false;
1152                 }
1153                 String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
1154                 if (list != null) {
1155                     for (String pkg : list) {
1156                         if (pkg.equals(pkgName)) {
1157                             removed = ADDED;
1158                             return true;
1159                         }
1160                     }
1161                 }
1162             }
1163             return false;
1164         }
1165     }
1166 
invokeMovePackage(String pkgName, int flags, GenericReceiver receiver)1167     public boolean invokeMovePackage(String pkgName, int flags, GenericReceiver receiver)
1168             throws Exception {
1169         throw new UnsupportedOperationException();
1170     }
1171 
invokeMovePackageFail(String pkgName, int flags, int errCode)1172     private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception {
1173         throw new UnsupportedOperationException();
1174     }
1175 
getDefaultInstallLoc()1176     private int getDefaultInstallLoc() {
1177         int origDefaultLoc = PackageInfo.INSTALL_LOCATION_AUTO;
1178         try {
1179             origDefaultLoc = Settings.Global.getInt(mContext.getContentResolver(),
1180                     Settings.Global.DEFAULT_INSTALL_LOCATION);
1181         } catch (SettingNotFoundException e1) {
1182         }
1183         return origDefaultLoc;
1184     }
1185 
setInstallLoc(int loc)1186     private void setInstallLoc(int loc) {
1187         Settings.Global.putInt(mContext.getContentResolver(),
1188                 Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
1189     }
1190 
1191     /*
1192      * Tests for moving apps between internal and external storage
1193      */
1194     /*
1195      * Utility function that reads a apk bundled as a raw resource
1196      * copies it into own data directory and invokes
1197      * PackageManager api to install first and then replace it
1198      * again.
1199      */
1200 
moveFromRawResource(String outFileName, int rawResId, int installFlags, int moveFlags, boolean cleanUp, boolean fail, int result)1201     private void moveFromRawResource(String outFileName, int rawResId, int installFlags,
1202             int moveFlags, boolean cleanUp, boolean fail, int result) throws Exception {
1203         int origDefaultLoc = getDefaultInstallLoc();
1204         InstallParams ip = null;
1205         try {
1206             setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1207             // Install first
1208             ip = installFromRawResource("install.apk", rawResId, installFlags, false,
1209                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1210             ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1211             if (fail) {
1212                 assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1213                 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1214                 assertNotNull(info);
1215                 assertEquals(oldAppInfo.flags, info.flags);
1216             } else {
1217                 // Create receiver based on expRetCode
1218                 MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
1219                 boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags, receiver);
1220                 assertTrue(retCode);
1221                 ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
1222                 assertNotNull("ApplicationInfo for recently installed application should exist",
1223                         info);
1224                 if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
1225                     assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should NOT be set",
1226                             (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
1227                     assertStartsWith("Native library dir should be in dataDir",
1228                             info.dataDir, info.nativeLibraryDir);
1229                 } else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0) {
1230                     assertTrue("ApplicationInfo.FLAG_EXTERNAL_STORAGE flag should be set",
1231                             (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
1232                     assertStartsWith("Native library dir should point to ASEC",
1233                             SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir);
1234                 }
1235             }
1236         } catch (NameNotFoundException e) {
1237             failStr("Pkg hasnt been installed correctly");
1238         } finally {
1239             if (ip != null) {
1240                 cleanUpInstall(ip);
1241             }
1242             // Restore default install location
1243             setInstallLoc(origDefaultLoc);
1244         }
1245     }
1246 
sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail, int result)1247     private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail,
1248             int result) throws Exception {
1249         moveFromRawResource("install.apk",
1250                 R.raw.install, installFlags, moveFlags, true,
1251                 fail, result);
1252     }
1253 
1254     @LargeTest
testMoveAppInternalToExternal()1255     public void testMoveAppInternalToExternal() throws Exception {
1256         // Do not run on devices with emulated external storage.
1257         if (Environment.isExternalStorageEmulated()) {
1258             return;
1259         }
1260 
1261         int installFlags = PackageManager.INSTALL_INTERNAL;
1262         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1263         boolean fail = false;
1264         int result = PackageManager.MOVE_SUCCEEDED;
1265         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1266     }
1267 
1268     @Suppress
1269     @LargeTest
testMoveAppInternalToInternal()1270     public void testMoveAppInternalToInternal() throws Exception {
1271         int installFlags = PackageManager.INSTALL_INTERNAL;
1272         int moveFlags = PackageManager.MOVE_INTERNAL;
1273         boolean fail = true;
1274         int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
1275         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
1276     }
1277 
1278     @LargeTest
testMoveAppFailInternalToExternalDelete()1279     public void testMoveAppFailInternalToExternalDelete() throws Exception {
1280         // Do not run on devices with emulated external storage.
1281         if (Environment.isExternalStorageEmulated()) {
1282             return;
1283         }
1284 
1285         int installFlags = 0;
1286         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
1287         boolean fail = true;
1288         final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST;
1289 
1290         int rawResId = R.raw.install;
1291         int origDefaultLoc = getDefaultInstallLoc();
1292         InstallParams ip = null;
1293         try {
1294             PackageManager pm = getPm();
1295             setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
1296             // Install first
1297             ip = installFromRawResource("install.apk", R.raw.install, installFlags, false,
1298                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1299             // Delete the package now retaining data.
1300             GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1301             invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
1302             assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
1303         } catch (Exception e) {
1304             failStr(e);
1305         } finally {
1306             if (ip != null) {
1307                 cleanUpInstall(ip);
1308             }
1309             // Restore default install location
1310             setInstallLoc(origDefaultLoc);
1311         }
1312     }
1313 
1314     /*---------- Recommended install location tests ----*/
1315     /*
1316      * PrecedenceSuffixes:
1317      * Flag : FlagI, FlagE, FlagF
1318      * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
1319      * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
1320      * Existing: Existing suffix absent if not existing.
1321      * User: UserI, UserE, UserA, User suffix absent if not existing.
1322      *
1323      */
1324 
1325     /*
1326      * Install an app on internal flash
1327      */
1328     @LargeTest
testFlagI()1329     public void testFlagI() throws Exception {
1330         sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
1331     }
1332 
1333     /*
1334      * Install an app with both internal and manifest option set.
1335      * should install on internal.
1336      */
1337     @LargeTest
testFlagIManifestI()1338     public void testFlagIManifestI() throws Exception {
1339         installFromRawResource("install.apk", R.raw.install_loc_internal,
1340                 PackageManager.INSTALL_INTERNAL,
1341                 true,
1342                 false, -1,
1343                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1344     }
1345     /*
1346      * Install an app with both internal and manifest preference for
1347      * preferExternal. Should install on internal.
1348      */
1349     @LargeTest
testFlagIManifestE()1350     public void testFlagIManifestE() throws Exception {
1351         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1352                 PackageManager.INSTALL_INTERNAL,
1353                 true,
1354                 false, -1,
1355                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1356     }
1357     /*
1358      * Install an app with both internal and manifest preference for
1359      * auto. should install internal.
1360      */
1361     @LargeTest
testFlagIManifestA()1362     public void testFlagIManifestA() throws Exception {
1363         installFromRawResource("install.apk", R.raw.install_loc_auto,
1364                 PackageManager.INSTALL_INTERNAL,
1365                 true,
1366                 false, -1,
1367                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1368     }
1369 
1370     /*
1371      * The following test functions verify install location for existing apps.
1372      * ie existing app can be installed internally or externally. If install
1373      * flag is explicitly set it should override current location. If manifest location
1374      * is set, that should over ride current location too. if not the existing install
1375      * location should be honoured.
1376      * testFlagI/E/F/ExistingI/E -
1377      */
1378     @LargeTest
testFlagIExistingI()1379     public void testFlagIExistingI() throws Exception {
1380         int iFlags = PackageManager.INSTALL_INTERNAL;
1381         int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
1382         // First install.
1383         installFromRawResource("install.apk", R.raw.install,
1384                 iFlags,
1385                 false,
1386                 false, -1,
1387                 -1);
1388         // Replace now
1389         installFromRawResource("install.apk", R.raw.install,
1390                 rFlags,
1391                 true,
1392                 false, -1,
1393                 -1);
1394     }
1395 
1396     /*
1397      * The following set of tests verify the installation of apps with
1398      * install location attribute set to internalOnly, preferExternal and auto.
1399      * The manifest option should dictate the install location.
1400      * public void testManifestI/E/A
1401      * TODO out of memory fall back behaviour.
1402      */
1403     @LargeTest
testManifestI()1404     public void testManifestI() throws Exception {
1405         installFromRawResource("install.apk", R.raw.install_loc_internal,
1406                 0,
1407                 true,
1408                 false, -1,
1409                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1410     }
1411 
1412     @LargeTest
testManifestE()1413     public void testManifestE() throws Exception {
1414         // Do not run on devices with emulated external storage.
1415         if (Environment.isExternalStorageEmulated()) {
1416             return;
1417         }
1418 
1419         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1420                 0,
1421                 true,
1422                 false, -1,
1423                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1424     }
1425 
1426     @LargeTest
testManifestA()1427     public void testManifestA() throws Exception {
1428         installFromRawResource("install.apk", R.raw.install_loc_auto,
1429                 0,
1430                 true,
1431                 false, -1,
1432                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1433     }
1434 
1435     /*
1436      * The following set of tests verify the installation of apps
1437      * with install location attribute set to internalOnly, preferExternal and auto
1438      * for already existing apps. The manifest option should take precedence.
1439      * TODO add out of memory fall back behaviour.
1440      * testManifestI/E/AExistingI/E
1441      */
1442     @LargeTest
testManifestIExistingI()1443     public void testManifestIExistingI() throws Exception {
1444         int iFlags = PackageManager.INSTALL_INTERNAL;
1445         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1446         // First install.
1447         installFromRawResource("install.apk", R.raw.install,
1448                 iFlags,
1449                 false,
1450                 false, -1,
1451                 -1);
1452         // Replace now
1453         installFromRawResource("install.apk", R.raw.install_loc_internal,
1454                 rFlags,
1455                 true,
1456                 false, -1,
1457                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1458     }
1459 
1460     @LargeTest
testManifestEExistingI()1461     public void testManifestEExistingI() throws Exception {
1462         // Do not run on devices with emulated external storage.
1463         if (Environment.isExternalStorageEmulated()) {
1464             return;
1465         }
1466 
1467         int iFlags = PackageManager.INSTALL_INTERNAL;
1468         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1469         // First install.
1470         installFromRawResource("install.apk", R.raw.install,
1471                 iFlags,
1472                 false,
1473                 false, -1,
1474                 -1);
1475         // Replace now
1476         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
1477                 rFlags,
1478                 true,
1479                 false, -1,
1480                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
1481     }
1482 
1483     @LargeTest
testManifestAExistingI()1484     public void testManifestAExistingI() throws Exception {
1485         int iFlags = PackageManager.INSTALL_INTERNAL;
1486         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1487         // First install.
1488         installFromRawResource("install.apk", R.raw.install,
1489                 iFlags,
1490                 false,
1491                 false, -1,
1492                 -1);
1493         // Replace now
1494         installFromRawResource("install.apk", R.raw.install_loc_auto,
1495                 rFlags,
1496                 true,
1497                 false, -1,
1498                 PackageInfo.INSTALL_LOCATION_AUTO);
1499     }
1500 
1501     /*
1502      * The following set of tests check install location for existing
1503      * application based on user setting.
1504      */
getExpectedInstallLocation(int userSetting)1505     private int getExpectedInstallLocation(int userSetting) {
1506         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1507         boolean enable = getUserSettingSetInstallLocation();
1508         if (enable) {
1509             if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
1510                 iloc = PackageInfo.INSTALL_LOCATION_AUTO;
1511             } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
1512                 iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
1513             } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
1514                 iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
1515             }
1516         }
1517         return iloc;
1518     }
1519 
setExistingXUserX(int userSetting, int iFlags, int iloc)1520     private void setExistingXUserX(int userSetting, int iFlags, int iloc) throws Exception {
1521         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1522         // First install.
1523         installFromRawResource("install.apk", R.raw.install,
1524                 iFlags,
1525                 false,
1526                 false, -1,
1527                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1528         int origSetting = getDefaultInstallLoc();
1529         try {
1530             // Set user setting
1531             setInstallLoc(userSetting);
1532             // Replace now
1533             installFromRawResource("install.apk", R.raw.install,
1534                     rFlags,
1535                     true,
1536                     false, -1,
1537                     iloc);
1538         } finally {
1539             setInstallLoc(origSetting);
1540         }
1541     }
1542     @LargeTest
testExistingIUserI()1543     public void testExistingIUserI() throws Exception {
1544         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1545         int iFlags = PackageManager.INSTALL_INTERNAL;
1546         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1547     }
1548 
1549     @LargeTest
testExistingIUserE()1550     public void testExistingIUserE() throws Exception {
1551         // Do not run on devices with emulated external storage.
1552         if (Environment.isExternalStorageEmulated()) {
1553             return;
1554         }
1555 
1556         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1557         int iFlags = PackageManager.INSTALL_INTERNAL;
1558         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1559     }
1560 
1561     @LargeTest
testExistingIUserA()1562     public void testExistingIUserA() throws Exception {
1563         int userSetting = PackageHelper.APP_INSTALL_AUTO;
1564         int iFlags = PackageManager.INSTALL_INTERNAL;
1565         setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1566     }
1567 
1568     /*
1569      * The following set of tests verify that the user setting defines
1570      * the install location.
1571      *
1572      */
getUserSettingSetInstallLocation()1573     private boolean getUserSettingSetInstallLocation() {
1574         try {
1575             return Settings.Global.getInt(
1576                     mContext.getContentResolver(), Settings.Global.SET_INSTALL_LOCATION) != 0;
1577         } catch (SettingNotFoundException e1) {
1578         }
1579         return false;
1580     }
1581 
setUserSettingSetInstallLocation(boolean value)1582     private void setUserSettingSetInstallLocation(boolean value) {
1583         Settings.Global.putInt(mContext.getContentResolver(),
1584                 Settings.Global.SET_INSTALL_LOCATION, value ? 1 : 0);
1585     }
1586 
setUserX(boolean enable, int userSetting, int iloc)1587     private void setUserX(boolean enable, int userSetting, int iloc) throws Exception {
1588         boolean origUserSetting = getUserSettingSetInstallLocation();
1589         int origSetting = getDefaultInstallLoc();
1590         try {
1591             setUserSettingSetInstallLocation(enable);
1592             // Set user setting
1593             setInstallLoc(userSetting);
1594             // Replace now
1595             installFromRawResource("install.apk", R.raw.install,
1596                     0,
1597                     true,
1598                     false, -1,
1599                     iloc);
1600         } finally {
1601             // Restore original setting
1602             setUserSettingSetInstallLocation(origUserSetting);
1603             setInstallLoc(origSetting);
1604         }
1605     }
1606     @LargeTest
testUserI()1607     public void testUserI() throws Exception {
1608         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1609         int iloc = getExpectedInstallLocation(userSetting);
1610         setUserX(true, userSetting, iloc);
1611     }
1612 
1613     @LargeTest
testUserE()1614     public void testUserE() throws Exception {
1615         // Do not run on devices with emulated external storage.
1616         if (Environment.isExternalStorageEmulated()) {
1617             return;
1618         }
1619 
1620         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1621         int iloc = getExpectedInstallLocation(userSetting);
1622         setUserX(true, userSetting, iloc);
1623     }
1624 
1625     @LargeTest
testUserA()1626     public void testUserA() throws Exception {
1627         int userSetting = PackageHelper.APP_INSTALL_AUTO;
1628         int iloc = getExpectedInstallLocation(userSetting);
1629         setUserX(true, userSetting, iloc);
1630     }
1631 
1632     /*
1633      * The following set of tests turn on/off the basic
1634      * user setting for turning on install location.
1635      */
1636     @LargeTest
testUserPrefOffUserI()1637     public void testUserPrefOffUserI() throws Exception {
1638         int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
1639         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1640         setUserX(false, userSetting, iloc);
1641     }
1642 
1643     @LargeTest
testUserPrefOffUserE()1644     public void testUserPrefOffUserE() throws Exception {
1645         // Do not run on devices with emulated external storage.
1646         if (Environment.isExternalStorageEmulated()) {
1647             return;
1648         }
1649 
1650         int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
1651         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1652         setUserX(false, userSetting, iloc);
1653     }
1654 
1655     @LargeTest
testUserPrefOffA()1656     public void testUserPrefOffA() throws Exception {
1657         int userSetting = PackageHelper.APP_INSTALL_AUTO;
1658         int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
1659         setUserX(false, userSetting, iloc);
1660     }
1661 
1662     static final String BASE_PERMISSIONS_DEFINED[] = new String[] {
1663         PERM_PACKAGE, "com.android.unit_tests.install_decl_perm",
1664         PERM_DEFINED,
1665         "com.android.frameworks.coretests.NORMAL",
1666         "com.android.frameworks.coretests.DANGEROUS",
1667         "com.android.frameworks.coretests.SIGNATURE",
1668     };
1669 
1670     static final String BASE_PERMISSIONS_UNDEFINED[] = new String[] {
1671         PERM_PACKAGE, "com.android.frameworks.coretests.install_decl_perm",
1672         PERM_UNDEFINED,
1673         "com.android.frameworks.coretests.NORMAL",
1674         "com.android.frameworks.coretests.DANGEROUS",
1675         "com.android.frameworks.coretests.SIGNATURE",
1676     };
1677 
1678     static final String BASE_PERMISSIONS_USED[] = new String[] {
1679         PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
1680         PERM_USED,
1681         "com.android.frameworks.coretests.NORMAL",
1682         "com.android.frameworks.coretests.DANGEROUS",
1683         "com.android.frameworks.coretests.SIGNATURE",
1684     };
1685 
1686     static final String BASE_PERMISSIONS_NOTUSED[] = new String[] {
1687         PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
1688         PERM_NOTUSED,
1689         "com.android.frameworks.coretests.NORMAL",
1690         "com.android.frameworks.coretests.DANGEROUS",
1691         "com.android.frameworks.coretests.SIGNATURE",
1692     };
1693 
1694     static final String BASE_PERMISSIONS_SIGUSED[] = new String[] {
1695         PERM_PACKAGE, "com.android.frameworks.coretests.install_use_perm_good",
1696         PERM_USED,
1697         "com.android.frameworks.coretests.SIGNATURE",
1698         PERM_NOTUSED,
1699         "com.android.frameworks.coretests.NORMAL",
1700         "com.android.frameworks.coretests.DANGEROUS",
1701     };
1702 
1703     /*
1704      * Ensure that permissions are properly declared.
1705      */
1706     @LargeTest
testInstallDeclaresPermissions()1707     public void testInstallDeclaresPermissions() throws Exception {
1708         InstallParams ip = null;
1709         InstallParams ip2 = null;
1710         try {
1711             // **: Upon installing a package, are its declared permissions published?
1712 
1713             int iFlags = PackageManager.INSTALL_INTERNAL;
1714             int iApk = R.raw.install_decl_perm;
1715             ip = installFromRawResource("install.apk", iApk,
1716                     iFlags, false,
1717                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1718             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1719             assertPermissions(BASE_PERMISSIONS_DEFINED);
1720 
1721             // **: Upon installing package, are its permissions granted?
1722 
1723             int i2Flags = PackageManager.INSTALL_INTERNAL;
1724             int i2Apk = R.raw.install_use_perm_good;
1725             ip2 = installFromRawResource("install2.apk", i2Apk,
1726                     i2Flags, false,
1727                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1728             assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
1729             assertPermissions(BASE_PERMISSIONS_USED);
1730 
1731             // **: Upon removing but not deleting, are permissions retained?
1732 
1733             GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
1734 
1735             try {
1736                 invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
1737             } catch (Exception e) {
1738                 failStr(e);
1739             }
1740             assertPermissions(BASE_PERMISSIONS_DEFINED);
1741             assertPermissions(BASE_PERMISSIONS_USED);
1742 
1743             // **: Upon re-installing, are permissions retained?
1744 
1745             ip = installFromRawResource("install.apk", iApk,
1746                     iFlags | PackageManager.INSTALL_REPLACE_EXISTING, false,
1747                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1748             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1749             assertPermissions(BASE_PERMISSIONS_DEFINED);
1750             assertPermissions(BASE_PERMISSIONS_USED);
1751 
1752             // **: Upon deleting package, are all permissions removed?
1753 
1754             try {
1755                 invokeDeletePackage(ip.pkg.packageName, 0, receiver);
1756                 ip = null;
1757             } catch (Exception e) {
1758                 failStr(e);
1759             }
1760             assertPermissions(BASE_PERMISSIONS_UNDEFINED);
1761             assertPermissions(BASE_PERMISSIONS_NOTUSED);
1762 
1763             // **: Delete package using permissions; nothing to check here.
1764 
1765             GenericReceiver receiver2 = new DeleteReceiver(ip2.pkg.packageName);
1766             try {
1767                 invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
1768                 ip2 = null;
1769             } catch (Exception e) {
1770                 failStr(e);
1771             }
1772 
1773             // **: Re-install package using permissions; no permissions can be granted.
1774 
1775             ip2 = installFromRawResource("install2.apk", i2Apk,
1776                     i2Flags, false,
1777                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1778             assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
1779             assertPermissions(BASE_PERMISSIONS_NOTUSED);
1780 
1781             // **: Upon installing declaring package, are sig permissions granted
1782             // to other apps (but not other perms)?
1783 
1784             ip = installFromRawResource("install.apk", iApk,
1785                     iFlags, false,
1786                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1787             assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
1788             assertPermissions(BASE_PERMISSIONS_DEFINED);
1789             assertPermissions(BASE_PERMISSIONS_SIGUSED);
1790 
1791             // **: Re-install package using permissions; are all permissions granted?
1792 
1793             ip2 = installFromRawResource("install2.apk", i2Apk,
1794                     i2Flags | PackageManager.INSTALL_REPLACE_EXISTING, false,
1795                     false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
1796             assertInstall(ip2.pkg, i2Flags, ip2.pkg.installLocation);
1797             assertPermissions(BASE_PERMISSIONS_NOTUSED);
1798 
1799             // **: Upon deleting package, are all permissions removed?
1800 
1801             try {
1802                 invokeDeletePackage(ip.pkg.packageName, 0, receiver);
1803                 ip = null;
1804             } catch (Exception e) {
1805                 failStr(e);
1806             }
1807             assertPermissions(BASE_PERMISSIONS_UNDEFINED);
1808             assertPermissions(BASE_PERMISSIONS_NOTUSED);
1809 
1810             // **: Delete package using permissions; nothing to check here.
1811 
1812             try {
1813                 invokeDeletePackage(ip2.pkg.packageName, 0, receiver);
1814                 ip2 = null;
1815             } catch (Exception e) {
1816                 failStr(e);
1817             }
1818 
1819         } finally {
1820             if (ip2 != null) {
1821                 cleanUpInstall(ip2);
1822             }
1823             if (ip != null) {
1824                 cleanUpInstall(ip);
1825             }
1826         }
1827     }
1828 
1829     /*
1830      * The following series of tests are related to upgrading apps with
1831      * different certificates.
1832      */
1833     private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
1834 
1835     private int APP1_CERT1 = R.raw.install_app1_cert1;
1836 
1837     private int APP1_CERT2 = R.raw.install_app1_cert2;
1838 
1839     private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
1840 
1841     private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
1842 
1843     private int APP1_CERT3 = R.raw.install_app1_cert3;
1844 
1845     private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
1846 
1847     private int APP2_CERT1 = R.raw.install_app2_cert1;
1848 
1849     private int APP2_CERT2 = R.raw.install_app2_cert2;
1850 
1851     private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
1852 
1853     private int APP2_CERT3 = R.raw.install_app2_cert3;
1854 
replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode)1855     private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail,
1856             int retCode) throws Exception {
1857         int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1858         String apk1Name = "install1.apk";
1859         String apk2Name = "install2.apk";
1860         PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
1861         try {
1862             InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
1863                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1864             installFromRawResource(apk2Name, apk2, rFlags, false,
1865                     fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1866             return ip;
1867         } catch (Exception e) {
1868             failStr(e.getMessage());
1869         } finally {
1870             if (cleanUp) {
1871                 cleanUpInstall(pkg1.packageName);
1872             }
1873         }
1874         return null;
1875     }
1876 
1877     /*
1878      * Test that an app signed with two certificates can be upgraded by the
1879      * same app signed with two certificates.
1880      */
1881     @LargeTest
testReplaceMatchAllCerts()1882     public void testReplaceMatchAllCerts() throws Exception {
1883         replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
1884     }
1885 
1886     /*
1887      * Test that an app signed with two certificates cannot be upgraded
1888      * by an app signed with a different certificate.
1889      */
1890     @LargeTest
testReplaceMatchNoCerts1()1891     public void testReplaceMatchNoCerts1() throws Exception {
1892         replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
1893                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1894     }
1895 
1896     /*
1897      * Test that an app signed with two certificates cannot be upgraded
1898      * by an app signed with a different certificate.
1899      */
1900     @LargeTest
testReplaceMatchNoCerts2()1901     public void testReplaceMatchNoCerts2() throws Exception {
1902         replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
1903                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1904     }
1905 
1906     /*
1907      * Test that an app signed with two certificates cannot be upgraded by
1908      * an app signed with a subset of initial certificates.
1909      */
1910     @LargeTest
testReplaceMatchSomeCerts1()1911     public void testReplaceMatchSomeCerts1() throws Exception {
1912         replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
1913                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1914     }
1915 
1916     /*
1917      * Test that an app signed with two certificates cannot be upgraded by
1918      * an app signed with the last certificate.
1919      */
1920     @LargeTest
testReplaceMatchSomeCerts2()1921     public void testReplaceMatchSomeCerts2() throws Exception {
1922         replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
1923                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1924     }
1925 
1926     /*
1927      * Test that an app signed with a certificate can be upgraded by app
1928      * signed with a superset of certificates.
1929      */
1930     @LargeTest
testReplaceMatchMoreCerts()1931     public void testReplaceMatchMoreCerts() throws Exception {
1932         replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
1933                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1934     }
1935 
1936     /*
1937      * Test that an app signed with a certificate can be upgraded by app
1938      * signed with a superset of certificates. Then verify that the an app
1939      * signed with the original set of certs cannot upgrade the new one.
1940      */
1941     @LargeTest
testReplaceMatchMoreCertsReplaceSomeCerts()1942     public void testReplaceMatchMoreCertsReplaceSomeCerts() throws Exception {
1943         InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
1944                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1945         try {
1946             int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
1947             installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
1948                     false, -1,
1949                     PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
1950         } catch (Exception e) {
1951             failStr(e.getMessage());
1952         } finally {
1953             if (ip != null) {
1954                 cleanUpInstall(ip);
1955             }
1956         }
1957     }
1958 
1959     /**
1960      * The following tests are related to testing KeySets-based key rotation
1961      */
1962     /*
1963      * Check if an apk which does not specify an upgrade-keyset may be upgraded
1964      * by an apk which does
1965      */
testNoKSToUpgradeKS()1966     public void testNoKSToUpgradeKS() throws Exception {
1967         replaceCerts(R.raw.keyset_sa_unone, R.raw.keyset_sa_ua, true, false, -1);
1968     }
1969 
1970     /*
1971      * Check if an apk which does specify an upgrade-keyset may be downgraded to
1972      * an apk which does not
1973      */
testUpgradeKSToNoKS()1974     public void testUpgradeKSToNoKS() throws Exception {
1975         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_unone, true, false, -1);
1976     }
1977 
1978     /*
1979      * Check if an apk signed by a key other than the upgrade keyset can update
1980      * an app
1981      */
testUpgradeKSWithWrongKey()1982     public void testUpgradeKSWithWrongKey() throws Exception {
1983         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sb_ua, true, true,
1984                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1985     }
1986 
1987     /*
1988      * Check if an apk signed by its signing key, which is not an upgrade key,
1989      * can upgrade an app.
1990      */
testUpgradeKSWithWrongSigningKey()1991     public void testUpgradeKSWithWrongSigningKey() throws Exception {
1992         replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sa_ub, true, true,
1993                 PackageInstaller.STATUS_FAILURE_CONFLICT);
1994     }
1995 
1996     /*
1997      * Check if an apk signed by its upgrade key, which is not its signing key,
1998      * can upgrade an app.
1999      */
testUpgradeKSWithUpgradeKey()2000     public void testUpgradeKSWithUpgradeKey() throws Exception {
2001         replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sb_ub, true, false, -1);
2002     }
2003     /*
2004      * Check if an apk signed by its upgrade key, which is its signing key, can
2005      * upgrade an app.
2006      */
testUpgradeKSWithSigningUpgradeKey()2007     public void testUpgradeKSWithSigningUpgradeKey() throws Exception {
2008         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_ua, true, false, -1);
2009     }
2010 
2011     /*
2012      * Check if an apk signed by multiple keys, one of which is its upgrade key,
2013      * can upgrade an app.
2014      */
testMultipleUpgradeKSWithUpgradeKey()2015     public void testMultipleUpgradeKSWithUpgradeKey() throws Exception {
2016         replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sab_ua, true, false, -1);
2017     }
2018 
2019     /*
2020      * Check if an apk signed by multiple keys, one of which is its signing key,
2021      * but none of which is an upgrade key, can upgrade an app.
2022      */
testMultipleUpgradeKSWithSigningKey()2023     public void testMultipleUpgradeKSWithSigningKey() throws Exception {
2024         replaceCerts(R.raw.keyset_sau_ub, R.raw.keyset_sa_ua, true, true,
2025                 PackageInstaller.STATUS_FAILURE_CONFLICT);
2026     }
2027 
2028     /*
2029      * Check if an apk which defines multiple (two) upgrade keysets is
2030      * upgrade-able by either.
2031      */
testUpgradeKSWithMultipleUpgradeKeySets()2032     public void testUpgradeKSWithMultipleUpgradeKeySets() throws Exception {
2033         replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sa_ua, true, false, -1);
2034         replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sb_ub, true, false, -1);
2035     }
2036 
2037     /*
2038      * Check if an apk's sigs are changed after upgrading with a non-signing
2039      * key.
2040      *
2041      * TODO: consider checking against hard-coded Signatures in the Sig-tests
2042      */
testSigChangeAfterUpgrade()2043     public void testSigChangeAfterUpgrade() throws Exception {
2044         // install original apk and grab sigs
2045         installFromRawResource("tmp.apk", R.raw.keyset_sa_ub,
2046                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2047         PackageManager pm = getPm();
2048         String pkgName = "com.android.frameworks.coretests.keysets";
2049         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2050         assertTrue("Package should only have one signature, sig A",
2051                 pi.signatures.length == 1);
2052         String sigBefore = pi.signatures[0].toCharsString();
2053         // install apk signed by different upgrade KeySet
2054         installFromRawResource("tmp2.apk", R.raw.keyset_sb_ub,
2055                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
2056                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2057         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2058         assertTrue("Package should only have one signature, sig B",
2059                 pi.signatures.length == 1);
2060         String sigAfter = pi.signatures[0].toCharsString();
2061         assertFalse("Package signatures did not change after upgrade!",
2062                 sigBefore.equals(sigAfter));
2063         cleanUpInstall(pkgName);
2064     }
2065 
2066     /*
2067      * Check if an apk's sig is the same  after upgrading with a signing
2068      * key.
2069      */
testSigSameAfterUpgrade()2070     public void testSigSameAfterUpgrade() throws Exception {
2071         // install original apk and grab sigs
2072         installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
2073                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2074         PackageManager pm = getPm();
2075         String pkgName = "com.android.frameworks.coretests.keysets";
2076         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2077         assertTrue("Package should only have one signature, sig A",
2078                 pi.signatures.length == 1);
2079         String sigBefore = pi.signatures[0].toCharsString();
2080         // install apk signed by same upgrade KeySet
2081         installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
2082                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
2083                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2084         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2085         assertTrue("Package should only have one signature, sig A",
2086                 pi.signatures.length == 1);
2087         String sigAfter = pi.signatures[0].toCharsString();
2088         assertTrue("Package signatures changed after upgrade!",
2089                 sigBefore.equals(sigAfter));
2090         cleanUpInstall(pkgName);
2091     }
2092 
2093     /*
2094      * Check if an apk's sigs are the same after upgrading with an app with
2095      * a subset of the original signing keys.
2096      */
testSigRemovedAfterUpgrade()2097     public void testSigRemovedAfterUpgrade() throws Exception {
2098         // install original apk and grab sigs
2099         installFromRawResource("tmp.apk", R.raw.keyset_sab_ua,
2100                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2101         PackageManager pm = getPm();
2102         String pkgName = "com.android.frameworks.coretests.keysets";
2103         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2104         assertTrue("Package should have two signatures, sig A and sig B",
2105                 pi.signatures.length == 2);
2106         Set<String> sigsBefore = new HashSet<String>();
2107         for (int i = 0; i < pi.signatures.length; i++) {
2108             sigsBefore.add(pi.signatures[i].toCharsString());
2109         }
2110         // install apk signed subset upgrade KeySet
2111         installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
2112                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
2113                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2114         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2115         assertTrue("Package should only have one signature, sig A",
2116                 pi.signatures.length == 1);
2117         String sigAfter = pi.signatures[0].toCharsString();
2118         assertTrue("Original package signatures did not contain new sig",
2119                 sigsBefore.contains(sigAfter));
2120         cleanUpInstall(pkgName);
2121     }
2122 
2123     /*
2124      * Check if an apk's sigs are added to after upgrading with an app with
2125      * a superset of the original signing keys.
2126      */
testSigAddedAfterUpgrade()2127     public void testSigAddedAfterUpgrade() throws Exception {
2128         // install original apk and grab sigs
2129         installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
2130                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2131         PackageManager pm = getPm();
2132         String pkgName = "com.android.frameworks.coretests.keysets";
2133         PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2134         assertTrue("Package should only have one signature, sig A",
2135                 pi.signatures.length == 1);
2136         String sigBefore = pi.signatures[0].toCharsString();
2137         // install apk signed subset upgrade KeySet
2138         installFromRawResource("tmp2.apk", R.raw.keyset_sab_ua,
2139                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
2140                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2141         pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
2142         assertTrue("Package should have two signatures, sig A and sig B",
2143                 pi.signatures.length == 2);
2144         Set<String> sigsAfter = new HashSet<String>();
2145         for (int i = 0; i < pi.signatures.length; i++) {
2146             sigsAfter.add(pi.signatures[i].toCharsString());
2147         }
2148         assertTrue("Package signatures did not change after upgrade!",
2149                 sigsAfter.contains(sigBefore));
2150         cleanUpInstall(pkgName);
2151     }
2152 
2153     /*
2154      * Check if an apk gains signature-level permission after changing to the a
2155      * new signature, for which a permission should be granted.
2156      */
testUpgradeSigPermGained()2157     public void testUpgradeSigPermGained() throws Exception {
2158         // install apk which defines permission
2159         installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
2160                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2161         // install apk which uses permission but does not have sig
2162         installFromRawResource("permUse.apk", R.raw.keyset_permuse_sb_ua_ub,
2163                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2164         // verify that package does not have perm before
2165         PackageManager pm = getPm();
2166         String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
2167         String pkgName = "com.android.frameworks.coretests.keysets";
2168         String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
2169         assertFalse("keyset permission granted to app without same signature!",
2170                     pm.checkPermission(permName, pkgName)
2171                     == PackageManager.PERMISSION_GRANTED);
2172         // upgrade to apk with perm signature
2173         installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sa_ua_ub,
2174                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
2175                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2176         assertTrue("keyset permission not granted to app after upgrade to same sig",
2177                     pm.checkPermission(permName, pkgName)
2178                     == PackageManager.PERMISSION_GRANTED);
2179         cleanUpInstall(permPkgName);
2180         cleanUpInstall(pkgName);
2181     }
2182 
2183     /*
2184      * Check if an apk loses signature-level permission after changing to the a
2185      * new signature, from one which a permission should be granted.
2186      */
testUpgradeSigPermLost()2187     public void testUpgradeSigPermLost() throws Exception {
2188         // install apk which defines permission
2189         installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
2190                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2191         // install apk which uses permission, signed by same sig
2192         installFromRawResource("permUse.apk", R.raw.keyset_permuse_sa_ua_ub,
2193                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2194         // verify that package does not have perm before
2195         PackageManager pm = getPm();
2196         String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
2197         String pkgName = "com.android.frameworks.coretests.keysets";
2198         String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
2199         assertTrue("keyset permission not granted to app with same sig",
2200                     pm.checkPermission(permName, pkgName)
2201                     == PackageManager.PERMISSION_GRANTED);
2202         // upgrade to apk without perm signature
2203         installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sb_ua_ub,
2204                 PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
2205                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2206 
2207         assertFalse("keyset permission not revoked from app which upgraded to a "
2208                     + "different signature",
2209                     pm.checkPermission(permName, pkgName)
2210                     == PackageManager.PERMISSION_GRANTED);
2211         cleanUpInstall(permPkgName);
2212         cleanUpInstall(pkgName);
2213     }
2214 
2215     /**
2216      * The following tests are related to testing KeySets-based API
2217      */
2218 
2219     /*
2220      * testGetSigningKeySetNull - ensure getSigningKeySet() returns null on null
2221      * input and when calling a package other than that which made the call.
2222      */
testGetSigningKeySet()2223     public void testGetSigningKeySet() throws Exception {
2224         PackageManager pm = getPm();
2225         String mPkgName = mContext.getPackageName();
2226         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
2227         KeySet ks;
2228         try {
2229             ks = pm.getSigningKeySet(null);
2230             assertTrue(false); // should have thrown
2231         } catch (NullPointerException e) {
2232         }
2233         try {
2234             ks = pm.getSigningKeySet("keysets.test.bogus.package");
2235             assertTrue(false); // should have thrown
2236         } catch (IllegalArgumentException e) {
2237         }
2238         final InstallParams ip = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
2239                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2240         try {
2241             ks = pm.getSigningKeySet(otherPkgName);
2242             assertTrue(false); // should have thrown
2243         } catch (SecurityException e) {
2244         } finally {
2245             cleanUpInstall(ip);
2246         }
2247         ks = pm.getSigningKeySet(mContext.getPackageName());
2248         assertNotNull(ks);
2249     }
2250 
2251     /*
2252      * testGetKeySetByAlias - same as getSigningKeySet, but for keysets defined
2253      * by this package.
2254      */
testGetKeySetByAlias()2255     public void testGetKeySetByAlias() throws Exception {
2256         PackageManager pm = getPm();
2257         String mPkgName = mContext.getPackageName();
2258         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
2259         KeySet ks;
2260         try {
2261             ks = pm.getKeySetByAlias(null, null);
2262             assertTrue(false); // should have thrown
2263         } catch (NullPointerException e) {
2264         }
2265         try {
2266             ks = pm.getKeySetByAlias(null, "keysetBogus");
2267             assertTrue(false); // should have thrown
2268         } catch (NullPointerException e) {
2269         }
2270         try {
2271             ks = pm.getKeySetByAlias("keysets.test.bogus.package", null);
2272             assertTrue(false); // should have thrown
2273         } catch (NullPointerException e) {
2274         }
2275         try {
2276             ks = pm.getKeySetByAlias("keysets.test.bogus.package", "A");
2277             assertTrue(false); // should have thrown
2278         } catch(IllegalArgumentException e) {
2279         }
2280         try {
2281             ks = pm.getKeySetByAlias(mPkgName, "keysetBogus");
2282             assertTrue(false); // should have thrown
2283         } catch(IllegalArgumentException e) {
2284         }
2285 
2286         // make sure we can get a KeySet from our pkg
2287         ks = pm.getKeySetByAlias(mPkgName, "A");
2288         assertNotNull(ks);
2289 
2290         // and another
2291         final InstallParams ip = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
2292                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2293         try {
2294             ks = pm.getKeySetByAlias(otherPkgName, "A");
2295             assertNotNull(ks);
2296         } finally {
2297             cleanUpInstall(ip);
2298         }
2299     }
2300 
testIsSignedBy()2301     public void testIsSignedBy() throws Exception {
2302         PackageManager pm = getPm();
2303         String mPkgName = mContext.getPackageName();
2304         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
2305         KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
2306         KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
2307 
2308         try {
2309             assertFalse(pm.isSignedBy(null, null));
2310             assertTrue(false); // should have thrown
2311         } catch (NullPointerException e) {
2312         }
2313         try {
2314             assertFalse(pm.isSignedBy(null, mSigningKS));
2315             assertTrue(false); // should have thrown
2316         } catch (NullPointerException e) {
2317         }
2318         try {
2319             assertFalse(pm.isSignedBy(mPkgName, null));
2320             assertTrue(false); // should have thrown
2321         } catch (NullPointerException e) {
2322         }
2323         try {
2324             assertFalse(pm.isSignedBy("keysets.test.bogus.package", mDefinedKS));
2325         } catch(IllegalArgumentException e) {
2326         }
2327         assertFalse(pm.isSignedBy(mPkgName, mDefinedKS));
2328         assertFalse(pm.isSignedBy(mPkgName, new KeySet(new Binder())));
2329         assertTrue(pm.isSignedBy(mPkgName, mSigningKS));
2330 
2331         final InstallParams ip1 = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
2332                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2333         try {
2334             assertFalse(pm.isSignedBy(otherPkgName, mDefinedKS));
2335             assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
2336         } finally {
2337             cleanUpInstall(ip1);
2338         }
2339 
2340         final InstallParams ip2 = installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
2341                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2342         try {
2343             assertTrue(pm.isSignedBy(otherPkgName, mDefinedKS));
2344             assertTrue(pm.isSignedBy(otherPkgName, mSigningKS));
2345         } finally {
2346             cleanUpInstall(ip2);
2347         }
2348     }
2349 
testIsSignedByExactly()2350     public void testIsSignedByExactly() throws Exception {
2351         PackageManager pm = getPm();
2352         String mPkgName = mContext.getPackageName();
2353         String otherPkgName = "com.android.frameworks.coretests.keysets_api";
2354         KeySet mSigningKS = pm.getSigningKeySet(mPkgName);
2355         KeySet mDefinedKS = pm.getKeySetByAlias(mPkgName, "A");
2356         try {
2357             assertFalse(pm.isSignedBy(null, null));
2358             assertTrue(false); // should have thrown
2359         } catch (NullPointerException e) {
2360         }
2361         try {
2362             assertFalse(pm.isSignedBy(null, mSigningKS));
2363             assertTrue(false); // should have thrown
2364         } catch (NullPointerException e) {
2365         }
2366         try {
2367             assertFalse(pm.isSignedBy(mPkgName, null));
2368             assertTrue(false); // should have thrown
2369         } catch (NullPointerException e) {
2370         }
2371         try {
2372             assertFalse(pm.isSignedByExactly("keysets.test.bogus.package", mDefinedKS));
2373         } catch(IllegalArgumentException e) {
2374         }
2375         assertFalse(pm.isSignedByExactly(mPkgName, mDefinedKS));
2376         assertFalse(pm.isSignedByExactly(mPkgName, new KeySet(new Binder())));
2377         assertTrue(pm.isSignedByExactly(mPkgName, mSigningKS));
2378 
2379         final InstallParams ip1 = installFromRawResource("keysetApi.apk", R.raw.keyset_splat_api,
2380                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2381         try {
2382             assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
2383             assertTrue(pm.isSignedByExactly(otherPkgName, mSigningKS));
2384         } finally {
2385             cleanUpInstall(ip1);
2386         }
2387 
2388         final InstallParams ip2 = installFromRawResource("keysetApi.apk", R.raw.keyset_splata_api,
2389                 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2390         try {
2391             assertFalse(pm.isSignedByExactly(otherPkgName, mDefinedKS));
2392             assertFalse(pm.isSignedByExactly(otherPkgName, mSigningKS));
2393         } finally {
2394             cleanUpInstall(ip2);
2395         }
2396     }
2397 
2398 
2399 
2400     /**
2401      * The following tests are related to testing the checkSignatures api.
2402      */
checkSignatures(int apk1, int apk2, int expMatchResult)2403     private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception {
2404         checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
2405     }
2406 
2407     @LargeTest
testCheckSignaturesAllMatch()2408     public void testCheckSignaturesAllMatch() throws Exception {
2409         int apk1 = APP1_CERT1_CERT2;
2410         int apk2 = APP2_CERT1_CERT2;
2411         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2412     }
2413 
2414     @LargeTest
testCheckSignaturesNoMatch()2415     public void testCheckSignaturesNoMatch() throws Exception {
2416         int apk1 = APP1_CERT1;
2417         int apk2 = APP2_CERT2;
2418         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2419     }
2420 
2421     @LargeTest
testCheckSignaturesSomeMatch1()2422     public void testCheckSignaturesSomeMatch1() throws Exception {
2423         int apk1 = APP1_CERT1_CERT2;
2424         int apk2 = APP2_CERT1;
2425         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2426     }
2427 
2428     @LargeTest
testCheckSignaturesSomeMatch2()2429     public void testCheckSignaturesSomeMatch2() throws Exception {
2430         int apk1 = APP1_CERT1_CERT2;
2431         int apk2 = APP2_CERT2;
2432         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2433     }
2434 
2435     @LargeTest
testCheckSignaturesMoreMatch()2436     public void testCheckSignaturesMoreMatch() throws Exception {
2437         int apk1 = APP1_CERT1;
2438         int apk2 = APP2_CERT1_CERT2;
2439         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
2440     }
2441 
2442     @LargeTest
testCheckSignaturesUnknown()2443     public void testCheckSignaturesUnknown() throws Exception {
2444         int apk1 = APP1_CERT1_CERT2;
2445         int apk2 = APP2_CERT1_CERT2;
2446         String apk1Name = "install1.apk";
2447         String apk2Name = "install2.apk";
2448 
2449         final InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
2450                 false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2451         try {
2452             PackageManager pm = mContext.getPackageManager();
2453             // Delete app2
2454             File filesDir = mContext.getFilesDir();
2455             File outFile = new File(filesDir, apk2Name);
2456             int rawResId = apk2;
2457             Uri packageURI = getInstallablePackage(rawResId, outFile);
2458             PackageParser.Package pkg = parsePackage(packageURI);
2459             try {
2460                 getPi().uninstall(pkg.packageName,
2461                         PackageManager.DELETE_ALL_USERS,
2462                         null /*statusReceiver*/);
2463             } catch (IllegalArgumentException ignore) {
2464             }
2465             // Check signatures now
2466             int match = mContext.getPackageManager().checkSignatures(
2467                     ip.pkg.packageName, pkg.packageName);
2468             assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
2469         } finally {
2470             cleanUpInstall(ip);
2471         }
2472     }
2473 
2474     @LargeTest
testInstallNoCertificates()2475     public void testInstallNoCertificates() throws Exception {
2476         int apk1 = APP1_UNSIGNED;
2477         String apk1Name = "install1.apk";
2478 
2479         installFromRawResource(apk1Name, apk1, 0, false,
2480                 true, PackageInstaller.STATUS_FAILURE_INVALID,
2481                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2482     }
2483 
2484     /*
2485      * The following tests are related to apps using shared uids signed with
2486      * different certs.
2487      */
2488     private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
2489 
2490     private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
2491 
2492     private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
2493 
2494     private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
2495 
2496     private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
2497 
2498     private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
2499 
2500     private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
2501 
2502     private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
2503 
checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult)2504     private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail,
2505             int retCode, int expMatchResult) throws Exception {
2506         String apk1Name = "install1.apk";
2507         String apk2Name = "install2.apk";
2508         PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
2509         PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
2510 
2511         try {
2512             // Clean up before testing first.
2513             cleanUpInstall(pkg1.packageName);
2514             cleanUpInstall(pkg2.packageName);
2515             installFromRawResource(apk1Name, apk1, 0, false, false, -1,
2516                     PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2517             if (fail) {
2518                 installFromRawResource(apk2Name, apk2, 0, false, true, retCode,
2519                         PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2520             } else {
2521                 installFromRawResource(apk2Name, apk2, 0, false, false, -1,
2522                         PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2523                 int match = mContext.getPackageManager().checkSignatures(pkg1.packageName,
2524                         pkg2.packageName);
2525                 assertEquals(expMatchResult, match);
2526             }
2527         } finally {
2528             if (cleanUp) {
2529                 cleanUpInstall(pkg1.packageName);
2530                 cleanUpInstall(pkg2.packageName);
2531             }
2532         }
2533     }
2534 
2535     @LargeTest
testCheckSignaturesSharedAllMatch()2536     public void testCheckSignaturesSharedAllMatch() throws Exception {
2537         int apk1 = SHARED1_CERT1_CERT2;
2538         int apk2 = SHARED2_CERT1_CERT2;
2539         boolean fail = false;
2540         int retCode = -1;
2541         int expMatchResult = PackageManager.SIGNATURE_MATCH;
2542         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2543     }
2544 
2545     @LargeTest
testCheckSignaturesSharedNoMatch()2546     public void testCheckSignaturesSharedNoMatch() throws Exception {
2547         int apk1 = SHARED1_CERT1;
2548         int apk2 = SHARED2_CERT2;
2549         boolean fail = true;
2550         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2551         int expMatchResult = -1;
2552         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2553     }
2554 
2555     /*
2556      * Test that an app signed with cert1 and cert2 cannot be replaced when
2557      * signed with cert1 alone.
2558      */
2559     @LargeTest
testCheckSignaturesSharedSomeMatch1()2560     public void testCheckSignaturesSharedSomeMatch1() throws Exception {
2561         int apk1 = SHARED1_CERT1_CERT2;
2562         int apk2 = SHARED2_CERT1;
2563         boolean fail = true;
2564         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2565         int expMatchResult = -1;
2566         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2567     }
2568 
2569     /*
2570      * Test that an app signed with cert1 and cert2 cannot be replaced when
2571      * signed with cert2 alone.
2572      */
2573     @LargeTest
testCheckSignaturesSharedSomeMatch2()2574     public void testCheckSignaturesSharedSomeMatch2() throws Exception {
2575         int apk1 = SHARED1_CERT1_CERT2;
2576         int apk2 = SHARED2_CERT2;
2577         boolean fail = true;
2578         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2579         int expMatchResult = -1;
2580         checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
2581     }
2582 
2583     @LargeTest
testCheckSignaturesSharedUnknown()2584     public void testCheckSignaturesSharedUnknown() throws Exception {
2585         int apk1 = SHARED1_CERT1_CERT2;
2586         int apk2 = SHARED2_CERT1_CERT2;
2587         String apk1Name = "install1.apk";
2588         String apk2Name = "install2.apk";
2589         InstallParams ip1 = null;
2590 
2591         try {
2592             ip1 = installFromRawResource(apk1Name, apk1, 0, false,
2593                     false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2594             PackageManager pm = mContext.getPackageManager();
2595             // Delete app2
2596             PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
2597             try {
2598                 getPi().uninstall(
2599                         pkg.packageName, PackageManager.DELETE_ALL_USERS, null /*statusReceiver*/);
2600             } catch (IllegalArgumentException ignore) {
2601             }
2602             // Check signatures now
2603             int match = mContext.getPackageManager().checkSignatures(
2604                     ip1.pkg.packageName, pkg.packageName);
2605             assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
2606         } finally {
2607             if (ip1 != null) {
2608                 cleanUpInstall(ip1);
2609             }
2610         }
2611     }
2612 
2613     @LargeTest
testReplaceFirstSharedMatchAllCerts()2614     public void testReplaceFirstSharedMatchAllCerts() throws Exception {
2615         int apk1 = SHARED1_CERT1;
2616         int apk2 = SHARED2_CERT1;
2617         int rapk1 = SHARED1_CERT1;
2618         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2619         replaceCerts(apk1, rapk1, true, false, -1);
2620     }
2621 
2622     @LargeTest
testReplaceSecondSharedMatchAllCerts()2623     public void testReplaceSecondSharedMatchAllCerts() throws Exception {
2624         int apk1 = SHARED1_CERT1;
2625         int apk2 = SHARED2_CERT1;
2626         int rapk2 = SHARED2_CERT1;
2627         checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
2628         replaceCerts(apk2, rapk2, true, false, -1);
2629     }
2630 
2631     @LargeTest
testReplaceFirstSharedMatchSomeCerts()2632     public void testReplaceFirstSharedMatchSomeCerts() throws Exception {
2633         int apk1 = SHARED1_CERT1_CERT2;
2634         int apk2 = SHARED2_CERT1_CERT2;
2635         int rapk1 = SHARED1_CERT1;
2636         boolean fail = true;
2637         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2638         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2639         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
2640                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2641     }
2642 
2643     @LargeTest
testReplaceSecondSharedMatchSomeCerts()2644     public void testReplaceSecondSharedMatchSomeCerts() throws Exception {
2645         int apk1 = SHARED1_CERT1_CERT2;
2646         int apk2 = SHARED2_CERT1_CERT2;
2647         int rapk2 = SHARED2_CERT1;
2648         boolean fail = true;
2649         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2650         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2651         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
2652                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2653     }
2654 
2655     @LargeTest
testReplaceFirstSharedMatchNoCerts()2656     public void testReplaceFirstSharedMatchNoCerts() throws Exception {
2657         int apk1 = SHARED1_CERT1;
2658         int apk2 = SHARED2_CERT1;
2659         int rapk1 = SHARED1_CERT2;
2660         boolean fail = true;
2661         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2662         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2663         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
2664                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2665     }
2666 
2667     @LargeTest
testReplaceSecondSharedMatchNoCerts()2668     public void testReplaceSecondSharedMatchNoCerts() throws Exception {
2669         int apk1 = SHARED1_CERT1;
2670         int apk2 = SHARED2_CERT1;
2671         int rapk2 = SHARED2_CERT2;
2672         boolean fail = true;
2673         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2674         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2675         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
2676                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2677     }
2678 
2679     @LargeTest
testReplaceFirstSharedMatchMoreCerts()2680     public void testReplaceFirstSharedMatchMoreCerts() throws Exception {
2681         int apk1 = SHARED1_CERT1;
2682         int apk2 = SHARED2_CERT1;
2683         int rapk1 = SHARED1_CERT1_CERT2;
2684         boolean fail = true;
2685         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2686         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2687         installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
2688                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2689     }
2690 
2691     @LargeTest
testReplaceSecondSharedMatchMoreCerts()2692     public void testReplaceSecondSharedMatchMoreCerts() throws Exception {
2693         int apk1 = SHARED1_CERT1;
2694         int apk2 = SHARED2_CERT1;
2695         int rapk2 = SHARED2_CERT1_CERT2;
2696         boolean fail = true;
2697         int retCode = PackageInstaller.STATUS_FAILURE_CONFLICT;
2698         checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
2699         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
2700                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2701     }
2702 
2703     /**
2704      * Unknown features should be allowed to install. This prevents older phones
2705      * from rejecting new packages that specify features that didn't exist when
2706      * an older phone existed. All older phones are assumed to have those
2707      * features.
2708      * <p>
2709      * Right now we allow all packages to be installed regardless of their
2710      * features.
2711      */
2712     @LargeTest
testUsesFeatureUnknownFeature()2713     public void testUsesFeatureUnknownFeature() throws Exception {
2714         int retCode = PackageManager.INSTALL_SUCCEEDED;
2715         installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, false, retCode,
2716                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2717     }
2718 
2719     @LargeTest
testInstallNonexistentFile()2720     public void testInstallNonexistentFile() throws Exception {
2721         int retCode = PackageInstaller.STATUS_FAILURE_INVALID;
2722         File invalidFile = new File("/nonexistent-file.apk");
2723         invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
2724     }
2725 
2726     @SmallTest
testGetVerifierDeviceIdentity()2727     public void testGetVerifierDeviceIdentity() throws Exception {
2728         PackageManager pm = getPm();
2729         VerifierDeviceIdentity id = pm.getVerifierDeviceIdentity();
2730 
2731         assertNotNull("Verifier device identity should not be null", id);
2732     }
2733 
testGetInstalledPackages()2734     public void testGetInstalledPackages() throws Exception {
2735         List<PackageInfo> packages = getPm().getInstalledPackages(0);
2736         assertNotNull("installed packages cannot be null", packages);
2737         assertTrue("installed packages cannot be empty", packages.size() > 0);
2738     }
2739 
testGetUnInstalledPackages()2740     public void testGetUnInstalledPackages() throws Exception {
2741         List<PackageInfo> packages = getPm().getInstalledPackages(
2742                 PackageManager.MATCH_UNINSTALLED_PACKAGES);
2743         assertNotNull("installed packages cannot be null", packages);
2744         assertTrue("installed packages cannot be empty", packages.size() > 0);
2745     }
2746 
2747     /**
2748      * Test that getInstalledPackages returns all the data specified in flags.
2749      */
testGetInstalledPackagesAll()2750     public void testGetInstalledPackagesAll() throws Exception {
2751         final int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
2752                 | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
2753                 | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
2754                 | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
2755                 | PackageManager.GET_SIGNATURES | PackageManager.MATCH_UNINSTALLED_PACKAGES;
2756 
2757         final InstallParams ip =
2758                 installFromRawResource("install.apk", R.raw.install_complete_package_info,
2759                         0 /*flags*/, false /*cleanUp*/, false /*fail*/, -1 /*result*/,
2760                         PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2761         try {
2762             final List<PackageInfo> packages = getPm().getInstalledPackages(flags);
2763             assertNotNull("installed packages cannot be null", packages);
2764             assertTrue("installed packages cannot be empty", packages.size() > 0);
2765 
2766             PackageInfo packageInfo = null;
2767 
2768             // Find the package with all components specified in the AndroidManifest
2769             // to ensure no null values
2770             for (PackageInfo pi : packages) {
2771                 if ("com.android.frameworks.coretests.install_complete_package_info"
2772                         .equals(pi.packageName)) {
2773                     packageInfo = pi;
2774                     break;
2775                 }
2776             }
2777             assertNotNull("activities should not be null", packageInfo.activities);
2778             assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
2779             assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
2780             assertNotNull("permissions should not be null", packageInfo.permissions);
2781             assertNotNull("providers should not be null", packageInfo.providers);
2782             assertNotNull("receivers should not be null", packageInfo.receivers);
2783             assertNotNull("services should not be null", packageInfo.services);
2784             assertNotNull("signatures should not be null", packageInfo.signatures);
2785         } finally {
2786             cleanUpInstall(ip);
2787         }
2788     }
2789 
2790     /**
2791      * Test that getInstalledPackages returns all the data specified in
2792      * flags when the GET_UNINSTALLED_PACKAGES flag is set.
2793      */
testGetUnInstalledPackagesAll()2794     public void testGetUnInstalledPackagesAll() throws Exception {
2795         final int flags = PackageManager.MATCH_UNINSTALLED_PACKAGES
2796                 | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
2797                 | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
2798                 | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
2799                 | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
2800                 | PackageManager.GET_SIGNATURES;
2801 
2802         // first, install the package
2803         final InstallParams ip =
2804                 installFromRawResource("install.apk", R.raw.install_complete_package_info,
2805                         0 /*flags*/, false /*cleanUp*/, false /*fail*/, -1 /*result*/,
2806                         PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
2807         try {
2808             // then, remove it, keeping it's data around
2809             final GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
2810             invokeDeletePackage(ip.pkg.packageName, PackageManager.DELETE_KEEP_DATA, receiver);
2811 
2812             final List<PackageInfo> packages = getPm().getInstalledPackages(flags);
2813             assertNotNull("installed packages cannot be null", packages);
2814             assertTrue("installed packages cannot be empty", packages.size() > 0);
2815 
2816             PackageInfo packageInfo = null;
2817 
2818             // Find the package with all components specified in the AndroidManifest
2819             // to ensure no null values
2820             for (PackageInfo pi : packages) {
2821                 if ("com.android.frameworks.coretests.install_complete_package_info"
2822                         .equals(pi.packageName)) {
2823                     packageInfo = pi;
2824                     break;
2825                 }
2826             }
2827             assertNotNull("activities should not be null", packageInfo.activities);
2828             assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
2829             assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
2830             assertNotNull("permissions should not be null", packageInfo.permissions);
2831             assertNotNull("providers should not be null", packageInfo.providers);
2832             assertNotNull("receivers should not be null", packageInfo.receivers);
2833             assertNotNull("services should not be null", packageInfo.services);
2834             assertNotNull("signatures should not be null", packageInfo.signatures);
2835         } finally {
2836             cleanUpInstall(ip);
2837         }
2838     }
2839 
2840     @Suppress
testInstall_BadDex_CleanUp()2841     public void testInstall_BadDex_CleanUp() throws Exception {
2842         int retCode = PackageInstaller.STATUS_FAILURE_INVALID;
2843         installFromRawResource("install.apk", R.raw.install_bad_dex, 0, true, true, retCode,
2844                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
2845     }
2846 
2847     private static class TestDexModuleRegisterCallback
2848             extends PackageManager.DexModuleRegisterCallback {
2849         private String mDexModulePath = null;
2850         private boolean mSuccess = false;
2851         private String mMessage = null;
2852         CountDownLatch doneSignal = new CountDownLatch(1);
2853 
2854         @Override
onDexModuleRegistered(String dexModulePath, boolean success, String message)2855         public void onDexModuleRegistered(String dexModulePath, boolean success, String message) {
2856             mDexModulePath = dexModulePath;
2857             mSuccess = success;
2858             mMessage = message;
2859             doneSignal.countDown();
2860         }
2861 
waitTillDone()2862         boolean waitTillDone() {
2863             long startTime = System.currentTimeMillis();
2864             while (System.currentTimeMillis() - startTime < MAX_WAIT_TIME) {
2865                 try {
2866                     return doneSignal.await(MAX_WAIT_TIME, TimeUnit.MILLISECONDS);
2867                 } catch (InterruptedException e) {
2868                     Log.i(TAG, "Interrupted during sleep", e);
2869                 }
2870             }
2871             return false;
2872         }
2873 
2874     }
2875 
2876     // Verify that the base code path cannot be registered.
testRegisterDexModuleBaseCode()2877     public void testRegisterDexModuleBaseCode() throws Exception {
2878         PackageManager pm = getPm();
2879         ApplicationInfo info = getContext().getApplicationInfo();
2880         TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
2881         pm.registerDexModule(info.getBaseCodePath(), callback);
2882         assertTrue(callback.waitTillDone());
2883         assertEquals(info.getBaseCodePath(), callback.mDexModulePath);
2884         assertFalse("BaseCodePath should not be registered", callback.mSuccess);
2885     }
2886 
2887     // Verify thatmodules which are not own by the calling package are not registered.
testRegisterDexModuleNotOwningModule()2888     public void testRegisterDexModuleNotOwningModule() throws Exception {
2889         TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
2890         String moduleBelongingToOtherPackage = "/data/user/0/com.google.android.gms/module.apk";
2891         getPm().registerDexModule(moduleBelongingToOtherPackage, callback);
2892         assertTrue(callback.waitTillDone());
2893         assertEquals(moduleBelongingToOtherPackage, callback.mDexModulePath);
2894         assertTrue(callback.waitTillDone());
2895         assertFalse("Only modules belonging to the calling package can be registered",
2896                 callback.mSuccess);
2897     }
2898 
2899     // Verify that modules owned by the package are successfully registered.
testRegisterDexModuleSuccessfully()2900     public void testRegisterDexModuleSuccessfully() throws Exception {
2901         ApplicationInfo info = getContext().getApplicationInfo();
2902         // Copy the main apk into the data folder and use it as a "module".
2903         File dexModuleDir = new File(info.dataDir, "module-dir");
2904         File dexModule = new File(dexModuleDir, "module.apk");
2905         try {
2906             assertNotNull(FileUtils.createDir(
2907                     dexModuleDir.getParentFile(), dexModuleDir.getName()));
2908             Files.copy(Paths.get(info.getBaseCodePath()), dexModule.toPath(),
2909                     StandardCopyOption.REPLACE_EXISTING);
2910             TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
2911             getPm().registerDexModule(dexModule.toString(), callback);
2912             assertTrue(callback.waitTillDone());
2913             assertEquals(dexModule.toString(), callback.mDexModulePath);
2914             assertTrue(callback.waitTillDone());
2915             assertTrue(callback.mMessage, callback.mSuccess);
2916 
2917             // NOTE:
2918             // This actually verifies internal behaviour which might change. It's not
2919             // ideal but it's the best we can do since there's no other place we can currently
2920             // write a better test.
2921             for(String isa : getAppDexInstructionSets(info)) {
2922                 Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.odex"));
2923                 Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.vdex"));
2924             }
2925         } finally {
2926             FileUtils.deleteContentsAndDir(dexModuleDir);
2927         }
2928     }
2929 
2930     // If the module does not exist on disk we should get a failure.
testRegisterDexModuleNotExists()2931     public void testRegisterDexModuleNotExists() throws Exception {
2932         ApplicationInfo info = getContext().getApplicationInfo();
2933         String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
2934         TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
2935         getPm().registerDexModule(nonExistentApk, callback);
2936         assertTrue(callback.waitTillDone());
2937         assertEquals(nonExistentApk, callback.mDexModulePath);
2938         assertTrue(callback.waitTillDone());
2939         assertFalse("DexModule registration should fail", callback.mSuccess);
2940     }
2941 
2942     // Copied from com.android.server.pm.InstructionSets because we don't have access to it here.
getAppDexInstructionSets(ApplicationInfo info)2943     private static String[] getAppDexInstructionSets(ApplicationInfo info) {
2944         if (info.primaryCpuAbi != null) {
2945             if (info.secondaryCpuAbi != null) {
2946                 return new String[] {
2947                         VMRuntime.getInstructionSet(info.primaryCpuAbi),
2948                         VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
2949             } else {
2950                 return new String[] {
2951                         VMRuntime.getInstructionSet(info.primaryCpuAbi) };
2952             }
2953         }
2954 
2955         return new String[] { VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]) };
2956     }
2957 
2958     /*---------- Recommended install location tests ----*/
2959     /*
2960      * TODO's
2961      * check version numbers for upgrades
2962      * check permissions of installed packages
2963      * how to do tests on updated system apps?
2964      * verify updates to system apps cannot be installed on the sdcard.
2965      */
2966 }
2967