• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.cts;
18 
19 import static android.Manifest.permission.DELETE_PACKAGES;
20 import static android.Manifest.permission.INSTALL_PACKAGES;
21 import static android.Manifest.permission.INSTALL_TEST_ONLY_PACKAGE;
22 import static android.Manifest.permission.QUARANTINE_APPS;
23 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
24 import static android.content.Context.RECEIVER_EXPORTED;
25 import static android.content.Intent.FLAG_EXCLUDE_STOPPED_PACKAGES;
26 import static android.content.pm.ApplicationInfo.FLAG_HAS_CODE;
27 import static android.content.pm.ApplicationInfo.FLAG_INSTALLED;
28 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
29 import static android.content.pm.Flags.FLAG_ARCHIVING;
30 import static android.content.pm.Flags.FLAG_CLOUD_COMPILATION_PM;
31 import static android.content.pm.Flags.FLAG_GET_PACKAGE_INFO;
32 import static android.content.pm.Flags.FLAG_GET_PACKAGE_INFO_WITH_FD;
33 import static android.content.pm.Flags.FLAG_IMPROVE_HOME_APP_BEHAVIOR;
34 import static android.content.pm.Flags.FLAG_MIN_TARGET_SDK_24;
35 import static android.content.pm.Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX;
36 import static android.content.pm.Flags.FLAG_QUARANTINED_ENABLED;
37 import static android.content.pm.Flags.FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS;
38 import static android.content.pm.PackageInstaller.STATUS_FAILURE;
39 import static android.content.pm.PackageInstaller.STATUS_SUCCESS;
40 import static android.content.pm.PackageInstaller.SessionParams.MODE_FULL_INSTALL;
41 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
42 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
43 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
44 import static android.content.pm.PackageManager.DONT_KILL_APP;
45 import static android.content.pm.PackageManager.FLAG_SUSPEND_QUARANTINED;
46 import static android.content.pm.PackageManager.GET_ACTIVITIES;
47 import static android.content.pm.PackageManager.GET_INSTRUMENTATION;
48 import static android.content.pm.PackageManager.GET_META_DATA;
49 import static android.content.pm.PackageManager.GET_PERMISSIONS;
50 import static android.content.pm.PackageManager.GET_PROVIDERS;
51 import static android.content.pm.PackageManager.GET_RECEIVERS;
52 import static android.content.pm.PackageManager.GET_SERVICES;
53 import static android.content.pm.PackageManager.GET_SIGNATURES;
54 import static android.content.pm.PackageManager.MATCH_ANY_USER;
55 import static android.content.pm.PackageManager.MATCH_APEX;
56 import static android.content.pm.PackageManager.MATCH_ARCHIVED_PACKAGES;
57 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
58 import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
59 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
60 import static android.content.pm.PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
61 import static android.content.pm.PackageManager.MATCH_INSTANT;
62 import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
63 import static android.content.pm.PackageManager.MATCH_QUARANTINED_COMPONENTS;
64 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
65 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
66 import static android.content.pm.PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN;
67 import static android.content.pm.cts.PackageManagerShellCommandIncrementalTest.parsePackageDump;
68 import static android.os.UserHandle.CURRENT;
69 import static android.os.UserHandle.USER_CURRENT;
70 
71 import static com.google.common.truth.Truth.assertThat;
72 import static com.google.common.truth.Truth.assertWithMessage;
73 
74 import static org.junit.Assert.assertEquals;
75 import static org.junit.Assert.assertFalse;
76 import static org.junit.Assert.assertNotNull;
77 import static org.junit.Assert.assertNull;
78 import static org.junit.Assert.assertSame;
79 import static org.junit.Assert.assertTrue;
80 import static org.junit.Assert.fail;
81 import static org.junit.Assume.assumeTrue;
82 import static org.testng.Assert.assertThrows;
83 import static org.testng.Assert.expectThrows;
84 
85 import android.Manifest;
86 import android.annotation.NonNull;
87 import android.app.Activity;
88 import android.app.ActivityOptions;
89 import android.app.ActivityThread;
90 import android.app.Instrumentation;
91 import android.app.usage.StorageStats;
92 import android.app.usage.StorageStatsManager;
93 import android.content.BroadcastReceiver;
94 import android.content.ComponentName;
95 import android.content.Context;
96 import android.content.IIntentReceiver;
97 import android.content.IIntentSender;
98 import android.content.Intent;
99 import android.content.IntentFilter;
100 import android.content.IntentSender;
101 import android.content.ServiceConnection;
102 import android.content.cts.MockActivity;
103 import android.content.cts.MockContentProvider;
104 import android.content.cts.MockReceiver;
105 import android.content.cts.MockService;
106 import android.content.cts.R;
107 import android.content.pm.ActivityInfo;
108 import android.content.pm.ApplicationInfo;
109 import android.content.pm.ArchivedActivityInfo;
110 import android.content.pm.ArchivedPackageInfo;
111 import android.content.pm.ComponentInfo;
112 import android.content.pm.IPackageManager;
113 import android.content.pm.InstallSourceInfo;
114 import android.content.pm.InstrumentationInfo;
115 import android.content.pm.PackageInfo;
116 import android.content.pm.PackageInstaller;
117 import android.content.pm.PackageInstaller.SessionParams;
118 import android.content.pm.PackageItemInfo;
119 import android.content.pm.PackageManager;
120 import android.content.pm.PackageManager.ComponentEnabledSetting;
121 import android.content.pm.PackageManager.NameNotFoundException;
122 import android.content.pm.PermissionGroupInfo;
123 import android.content.pm.PermissionInfo;
124 import android.content.pm.ProviderInfo;
125 import android.content.pm.ResolveInfo;
126 import android.content.pm.ServiceInfo;
127 import android.content.pm.SharedLibraryInfo;
128 import android.content.pm.Signature;
129 import android.content.pm.SigningInfo;
130 import android.content.pm.SigningInfoException;
131 import android.content.pm.SuspendDialogInfo;
132 import android.content.pm.cts.PackageManagerShellCommandInstallTest.PackageBroadcastReceiver;
133 import android.content.pm.cts.util.AbandonAllPackageSessionsRule;
134 import android.content.res.Configuration;
135 import android.content.res.Resources;
136 import android.content.res.TypedArray;
137 import android.content.res.XmlResourceParser;
138 import android.graphics.drawable.BitmapDrawable;
139 import android.os.Build;
140 import android.os.Bundle;
141 import android.os.Environment;
142 import android.os.IBinder;
143 import android.os.ParcelFileDescriptor;
144 import android.os.Process;
145 import android.os.RemoteException;
146 import android.os.SystemClock;
147 import android.os.UserHandle;
148 import android.platform.test.annotations.AppModeFull;
149 import android.platform.test.annotations.RequiresFlagsDisabled;
150 import android.platform.test.annotations.RequiresFlagsEnabled;
151 import android.platform.test.flag.junit.CheckFlagsRule;
152 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
153 import android.provider.Settings;
154 import android.text.TextUtils;
155 import android.util.Log;
156 
157 import androidx.test.ext.junit.runners.AndroidJUnit4;
158 import androidx.test.filters.SdkSuppress;
159 import androidx.test.platform.app.InstrumentationRegistry;
160 import androidx.test.rule.ServiceTestRule;
161 import androidx.test.uiautomator.UiDevice;
162 
163 import com.android.compatibility.common.util.CddTest;
164 import com.android.compatibility.common.util.FileUtils;
165 import com.android.compatibility.common.util.PollingCheck;
166 import com.android.compatibility.common.util.SystemUtil;
167 import com.android.compatibility.common.util.TestUtils;
168 import com.android.internal.security.VerityUtils;
169 
170 import com.google.common.truth.Expect;
171 
172 import java.util.regex.Matcher;
173 import java.util.regex.Pattern;
174 import junit.framework.AssertionFailedError;
175 
176 import org.junit.After;
177 import org.junit.Before;
178 import org.junit.Rule;
179 import org.junit.Test;
180 import org.junit.runner.RunWith;
181 import org.xmlpull.v1.XmlPullParser;
182 import org.xmlpull.v1.XmlPullParserException;
183 
184 import java.io.BufferedReader;
185 import java.io.File;
186 import java.io.FileInputStream;
187 import java.io.FileOutputStream;
188 import java.io.IOException;
189 import java.io.InputStream;
190 import java.io.InputStreamReader;
191 import java.security.PublicKey;
192 import java.security.cert.Certificate;
193 import java.security.cert.CertificateFactory;
194 import java.util.ArrayList;
195 import java.util.Arrays;
196 import java.util.Collections;
197 import java.util.HashSet;
198 import java.util.Iterator;
199 import java.util.List;
200 import java.util.Set;
201 import java.util.concurrent.CompletableFuture;
202 import java.util.concurrent.CountDownLatch;
203 import java.util.concurrent.TimeUnit;
204 import java.util.concurrent.TimeoutException;
205 import java.util.concurrent.atomic.AtomicBoolean;
206 import java.util.function.Consumer;
207 import java.util.stream.Collectors;
208 
209 /**
210  * This test is based on the declarations in AndroidManifest.xml. We create mock declarations
211  * in AndroidManifest.xml just for test of PackageManager, and there are no corresponding parts
212  * of these declarations in test project.
213  */
214 @AppModeFull // TODO(Instant) Figure out which APIs should work.
215 @RunWith(AndroidJUnit4.class)
216 public class PackageManagerTest {
217     private static final String TAG = "PackageManagerTest";
218 
219     private Context mContext;
220     private PackageManager mPackageManager;
221     private Instrumentation mInstrumentation;
222     private static final String PACKAGE_NAME = "android.content.cts";
223     private static final String STUB_PACKAGE_NAME = "com.android.cts.stub";
224     private static final String APPLICATION_NAME = "android.content.cts.MockApplication";
225     private static final String ACTIVITY_ACTION_NAME = "android.intent.action.PMTEST";
226     private static final String MAIN_ACTION_NAME = "android.intent.action.MAIN";
227     private static final String SERVICE_ACTION_NAME =
228             "android.content.pm.cts.activity.PMTEST_SERVICE";
229     private static final String RECEIVER_ACTION_NAME =
230             "android.content.pm.cts.PackageManagerTest.PMTEST_RECEIVER";
231     private static final String GRANTED_PERMISSION_NAME = "android.permission.INTERNET";
232     private static final String NOT_GRANTED_PERMISSION_NAME = "android.permission.HARDWARE_TEST";
233     private static final String ACTIVITY_NAME = "android.content.pm.cts.TestPmActivity";
234     private static final String SERVICE_NAME = "android.content.pm.cts.TestPmService";
235     private static final String RECEIVER_NAME = "android.content.pm.cts.PmTestReceiver";
236     private static final String INSTRUMENT_NAME = "android.content.pm.cts.TestPmInstrumentation";
237     private static final String CALL_ABROAD_PERMISSION_NAME =
238             "android.content.cts.CALL_ABROAD_PERMISSION";
239     private static final String PROVIDER_NAME = "android.content.cts.MockContentProvider";
240     private static final String PERMISSIONGROUP_NAME = "android.permission-group.COST_MONEY";
241     private static final String PERMISSION_TREE_ROOT =
242             "android.content.cts.permission.TEST_DYNAMIC";
243     // Number of activities/activity-alias in AndroidManifest
244     private static final int NUM_OF_ACTIVITIES_IN_MANIFEST = 23;
245     public static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
246 
247     private static final String SHIM_APEX_PACKAGE_NAME = "com.android.apex.cts.shim";
248 
249     private static final int[] PACKAGE_INFO_MATCH_FLAGS = {MATCH_UNINSTALLED_PACKAGES,
250             MATCH_DISABLED_COMPONENTS, MATCH_SYSTEM_ONLY, MATCH_FACTORY_ONLY, MATCH_INSTANT,
251             MATCH_APEX, MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS};
252 
253     private static final String SAMPLE_APK_BASE = "/data/local/tmp/cts/content/";
254     private static final String EMPTY_APP_APK = SAMPLE_APK_BASE
255             + "CtsContentEmptyTestApp.apk";
256     private static final String LONG_PACKAGE_NAME_APK = SAMPLE_APK_BASE
257             + "CtsContentLongPackageNameTestApp.apk";
258     private static final String LONG_SHARED_USER_ID_APK = SAMPLE_APK_BASE
259             + "CtsContentLongSharedUserIdTestApp.apk";
260     private static final String MAX_PACKAGE_NAME_APK = SAMPLE_APK_BASE
261             + "CtsContentMaxPackageNameTestApp.apk";
262     private static final String MAX_SHARED_USER_ID_APK = SAMPLE_APK_BASE
263             + "CtsContentMaxSharedUserIdTestApp.apk";
264     private static final String LONG_LABEL_NAME_APK = SAMPLE_APK_BASE
265             + "CtsContentLongLabelNameTestApp.apk";
266     private static final String LONG_USES_PERMISSION_NAME_APK = SAMPLE_APK_BASE
267             + "CtsContentLongUsesPermissionNameTestApp.apk";
268     private static final String SHELL_NAME_APK = SAMPLE_APK_BASE
269             + "CtsContentShellTestApp.apk";
270     private static final String CTS_TARGET_SDK_23 = SAMPLE_APK_BASE + "CtsTargetSdk23TestApp.apk";
271     private static final String CTS_TARGET_SDK_24 = SAMPLE_APK_BASE + "CtsTargetSdk24TestApp.apk";
272 
273     private static final String TEST_ICON = SAMPLE_APK_BASE + "icon.png";
274     private static final String TEST_ICON_MONO = SAMPLE_APK_BASE + "icon_mono.png";
275     private static final String DIFF_SIGNER_CERTIFICATE = SAMPLE_APK_BASE + "cts-testkey1.x509.pem";
276 
277     private static final String EMPTY_APP_PACKAGE_NAME = "android.content.cts.emptytestapp";
278     private static final String EMPTY_APP_ACTIVITY_NAME =
279             "android.content.cts.emptytestapp.MockActivity";
280     private static final String EMPTY_APP_MAX_PACKAGE_NAME = "android.content.cts.emptytestapp27j"
281             + "EBRNRG3ozwBsGr1sVIM9U0bVTI2TdyIyeRkZgW4JrJefwNIBAmCg4AzqXiCvG6JjqA0uTCWSFu2YqAVxVd"
282             + "iRKAay19k5VFlSaM7QW9uhvlrLQqsTW01ofFzxNDbp2QfIFHZR6rebKzKBz6byQFM0DYQnYMwFWXjWkMPN"
283             + "dqkRLykoFLyBup53G68k2n8w";
284     private static final String EMPTY_APP_LONG_USES_PERMISSION_PACKAGE_NAME =
285             EMPTY_APP_PACKAGE_NAME + ".longusespermission";
286     private static final String SETTINGS_PROVIDER_PACKAGE_NAME = "com.android.providers.settings";
287     private static final String SHELL_PACKAGE_NAME = "com.android.shell";
288     private static final String CTS_TARGET_SDK_23_PACKAGE_NAME =
289             "android.content.cts.emptytestapp.sdk23";
290     private static final String CTS_TARGET_SDK_24_PACKAGE_NAME =
291             "android.content.cts.emptytestapp.sdk24";
292     private static final String HELLO_WORLD_PACKAGE_NAME = "com.example.helloworld";
293     private static final String HELLO_WORLD_APK = SAMPLE_APK_BASE + "HelloWorld5.apk";
294     private static final String HELLO_WORLD_DIFF_SIGNER_APK =
295             SAMPLE_APK_BASE + "HelloWorld5DifferentSigner.apk";
296     private static final String HELLO_WORLD_FLAGS_APK =
297             SAMPLE_APK_BASE + "HelloWorld5NonDefaultFlags.apk";
298     private static final String HELLO_WORLD_UPDATED_APK = SAMPLE_APK_BASE + "HelloWorld7.apk";
299     private static final String HELLO_WORLD_LOTS_OF_FLAGS_APK =
300             SAMPLE_APK_BASE + "HelloWorldLotsOfFlags.apk";
301     private static final String HELLO_WORLD_NON_UPDATABLE_SYSTEM_APK = SAMPLE_APK_BASE
302             + "HelloWorldNonUpdatableSystem.apk";
303     private static final String HELLO_WORLD_V1_APK = SAMPLE_APK_BASE
304             + "HelloWorldAppV1.apk";
305     private static final String HELLO_WORLD_V2_APK = SAMPLE_APK_BASE
306             + "HelloWorldAppV2.apk";
307 
308     private static final String HELLO_WORLD_SHARED_UID_APK = SAMPLE_APK_BASE
309             + "HelloWorldSharedUid.apk";
310 
311     private static final String HELLO_WORLD_SETTINGS = SAMPLE_APK_BASE
312             + "HelloWorldSettings.apk";
313 
314     private static final String HELLO_WORLD_SETTINGS2 = SAMPLE_APK_BASE
315             + "HelloWorldSettings2.apk";
316 
317     private static final String HELLO_WORLD_SETTINGS_PACKAGE_NAME = "android.test.settings";
318 
319     private static final String HELLO_WORLD_SETTINGS2_PACKAGE_NAME = "android.test.settings2";
320 
321     private static final String MOCK_LAUNCHER_PACKAGE_NAME = "android.content.cts.mocklauncherapp";
322     private static final String MOCK_LAUNCHER_APK = SAMPLE_APK_BASE
323             + "CtsContentMockLauncherTestApp.apk";
324     private static final String NON_EXISTENT_PACKAGE_NAME = "android.content.cts.nonexistent.pkg";
325     private static final String INVALID_PACKAGE_NAME = "@null_invalid#name";
326     private static final String STUB_PACKAGE_APK = SAMPLE_APK_BASE
327             + "CtsSyncAccountAccessStubs.apk";
328     private static final String STUB_PACKAGE_SPLIT =
329             SAMPLE_APK_BASE + "CtsSyncAccountAccessStubs_mdpi-v4.apk";
330     private static final String TEST_HW_NO_APP_STORAGE =
331             SAMPLE_APK_BASE + "HelloWorldNoAppStorage.apk";
332 
333     private static final int MAX_SAFE_LABEL_LENGTH = 1000;
334 
335     // For intent resolution tests
336     private static final String TAG_MANIFEST = "manifest";
337     private static final String MIME_GROUP = "mime_group";
338 
339     private static final ComponentName ACTIVITY_COMPONENT = new ComponentName(
340             PACKAGE_NAME, ACTIVITY_NAME);
341     private static final ComponentName SERVICE_COMPONENT = new ComponentName(
342             PACKAGE_NAME, SERVICE_NAME);
343     private static final ComponentName STUB_ACTIVITY_COMPONENT = ComponentName.createRelative(
344             STUB_PACKAGE_NAME, ".StubActivity");
345     private static final ComponentName STUB_SERVICE_COMPONENT = ComponentName.createRelative(
346             STUB_PACKAGE_NAME, ".StubService");
347     private static final ComponentName RESET_ENABLED_SETTING_ACTIVITY_COMPONENT =
348             ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockActivity");
349     private static final ComponentName RESET_ENABLED_SETTING_RECEIVER_COMPONENT =
350             ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockReceiver");
351     private static final ComponentName RESET_ENABLED_SETTING_SERVICE_COMPONENT =
352             ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockService");
353     private static final ComponentName RESET_ENABLED_SETTING_PROVIDER_COMPONENT =
354             ComponentName.createRelative(MOCK_LAUNCHER_PACKAGE_NAME, ".MockProvider");
355     static final String CTS_SHIM_PACKAGE_NAME = "com.android.cts.ctsshim";
356 
357     private final ServiceTestRule mServiceTestRule = new ServiceTestRule();
358 
359     @Rule
360     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
361     @Rule
362     public AbandonAllPackageSessionsRule mAbandonSessionsRule = new AbandonAllPackageSessionsRule();
363 
364     @Rule
365     public final Expect expect = Expect.create();
366 
367     private UiDevice mUiDevice;
368 
369     @Before
setup()370     public void setup() throws Exception {
371         mInstrumentation = InstrumentationRegistry.getInstrumentation();
372         mContext = mInstrumentation.getContext();
373         mPackageManager = mContext.getPackageManager();
374         mUiDevice = UiDevice.getInstance(mInstrumentation);
375     }
376 
377     @After
tearDown()378     public void tearDown() throws Exception {
379         uninstallPackage(EMPTY_APP_PACKAGE_NAME);
380         uninstallPackage(EMPTY_APP_MAX_PACKAGE_NAME);
381         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
382         uninstallPackage(MOCK_LAUNCHER_PACKAGE_NAME);
383         uninstallPackage(EMPTY_APP_LONG_USES_PERMISSION_PACKAGE_NAME);
384         uninstallPackage(CTS_TARGET_SDK_23_PACKAGE_NAME);
385         uninstallPackage(CTS_TARGET_SDK_24_PACKAGE_NAME);
386     }
387 
388     @Test
testQuery()389     public void testQuery() throws NameNotFoundException {
390         // Test query Intent Activity related methods
391 
392         Intent activityIntent = new Intent(ACTIVITY_ACTION_NAME);
393         String cmpActivityName = "android.content.pm.cts.TestPmCompare";
394         // List with different activities and the filter doesn't work,
395         List<ResolveInfo> listWithDiff = mPackageManager.queryIntentActivityOptions(
396                 new ComponentName(PACKAGE_NAME, cmpActivityName), null, activityIntent,
397                 PackageManager.ResolveInfoFlags.of(0));
398         checkActivityInfoName(ACTIVITY_NAME, listWithDiff);
399 
400         // List with the same activities to make filter work
401         List<ResolveInfo> listInSame = mPackageManager.queryIntentActivityOptions(
402                 new ComponentName(PACKAGE_NAME, ACTIVITY_NAME), null, activityIntent,
403                 PackageManager.ResolveInfoFlags.of(0));
404         assertEquals(0, listInSame.size());
405 
406         // Test queryIntentActivities
407         List<ResolveInfo> intentActivities =
408                 mPackageManager.queryIntentActivities(activityIntent,
409                         PackageManager.ResolveInfoFlags.of(0));
410         assertTrue(intentActivities.size() > 0);
411         checkActivityInfoName(ACTIVITY_NAME, intentActivities);
412 
413         // Test queryIntentActivitiesAsUser
414         List<ResolveInfo> intentActivitiesAsUser =
415                 mPackageManager.queryIntentActivitiesAsUser(activityIntent,
416                         PackageManager.ResolveInfoFlags.of(0),
417                         UserHandle.of(UserHandle.myUserId()));
418         assertTrue(intentActivitiesAsUser.size() > 0);
419         checkActivityInfoName(ACTIVITY_NAME, intentActivitiesAsUser);
420 
421 
422         // End of Test query Intent Activity related methods
423 
424         // Test queryInstrumentation
425         String targetPackage = "android";
426         List<InstrumentationInfo> instrumentations = mPackageManager.queryInstrumentation(
427                 targetPackage, 0);
428         checkInstrumentationInfoName(INSTRUMENT_NAME, instrumentations);
429 
430         // Test queryIntentServices
431         Intent serviceIntent = new Intent(SERVICE_ACTION_NAME);
432         List<ResolveInfo> services = mPackageManager.queryIntentServices(serviceIntent,
433                 PackageManager.ResolveInfoFlags.of(0));
434         checkServiceInfoName(SERVICE_NAME, services);
435 
436         // Test queryBroadcastReceivers
437         Intent broadcastIntent = new Intent(RECEIVER_ACTION_NAME);
438         List<ResolveInfo> broadcastReceivers =
439                 mPackageManager.queryBroadcastReceivers(broadcastIntent,
440                         PackageManager.ResolveInfoFlags.of(0));
441         checkActivityInfoName(RECEIVER_NAME, broadcastReceivers);
442 
443         // Test queryPermissionsByGroup, queryContentProviders
444         String testPermissionsGroup = "android.permission-group.COST_MONEY";
445         List<PermissionInfo> permissions = mPackageManager.queryPermissionsByGroup(
446                 testPermissionsGroup, PackageManager.GET_META_DATA);
447         checkPermissionInfoName(CALL_ABROAD_PERMISSION_NAME, permissions);
448 
449         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME,
450                 PackageManager.ApplicationInfoFlags.of(0));
451         List<ProviderInfo> providers = mPackageManager.queryContentProviders(PACKAGE_NAME,
452                 appInfo.uid, PackageManager.ComponentInfoFlags.of(0));
453         checkProviderInfoName(PROVIDER_NAME, providers);
454     }
455 
456     @Test
testStoppedPackagesQuery()457     public void testStoppedPackagesQuery() throws NameNotFoundException {
458         installPackage(HELLO_WORLD_APK);
459 
460         final Intent intent = new Intent(ACTIVITY_ACTION_NAME);
461         intent.addFlags(FLAG_EXCLUDE_STOPPED_PACKAGES);
462 
463         // Stopped after install.
464         {
465             final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent,
466                     PackageManager.ResolveInfoFlags.of(0));
467             assertFalse(containsActivityInfoName("com.example.helloworld.MainActivity", matches));
468         }
469 
470         launchMainActivity(HELLO_WORLD_PACKAGE_NAME);
471 
472         // Started.
473         {
474             final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent,
475                     PackageManager.ResolveInfoFlags.of(0));
476             assertTrue(containsActivityInfoName("com.example.helloworld.MainActivity", matches));
477         }
478 
479         assertEquals("", SystemUtil.runShellCommand("am force-stop " + HELLO_WORLD_PACKAGE_NAME));
480 
481         // Force stopped.
482         {
483             final List<ResolveInfo> matches = mPackageManager.queryIntentActivities(intent,
484                     PackageManager.ResolveInfoFlags.of(0));
485             assertFalse(containsActivityInfoName("com.example.helloworld.MainActivity", matches));
486         }
487     }
488 
launchMainActivity(String packageName)489     public static void launchMainActivity(String packageName) {
490         SystemUtil.runShellCommand("am start -W "
491                 + "--user " + Process.myUserHandle().getIdentifier() + " "
492                 + "-a android.intent.action.MAIN "
493                 + "-c android.intent.category.LAUNCHER "
494                 + packageName + "/.MainActivity");
495     }
496 
containsActivityInfoName(String expectedName, List<ResolveInfo> resolves)497     private boolean containsActivityInfoName(String expectedName, List<ResolveInfo> resolves) {
498         Iterator<ResolveInfo> infoIterator = resolves.iterator();
499         String current;
500         while (infoIterator.hasNext()) {
501             current = infoIterator.next().activityInfo.name;
502             if (current.equals(expectedName)) {
503                 return true;
504             }
505         }
506         return false;
507     }
508 
checkActivityInfoName(String expectedName, List<ResolveInfo> resolves)509     private void checkActivityInfoName(String expectedName, List<ResolveInfo> resolves) {
510         assertTrue(containsActivityInfoName(expectedName, resolves));
511     }
512 
checkServiceInfoName(String expectedName, List<ResolveInfo> resolves)513     private void checkServiceInfoName(String expectedName, List<ResolveInfo> resolves) {
514         boolean isContained = false;
515         Iterator<ResolveInfo> infoIterator = resolves.iterator();
516         String current;
517         while (infoIterator.hasNext()) {
518             current = infoIterator.next().serviceInfo.name;
519             if (current.equals(expectedName)) {
520                 isContained = true;
521                 break;
522             }
523         }
524         assertTrue(isContained);
525     }
526 
checkPermissionInfoName(String expectedName, List<PermissionInfo> permissions)527     private void checkPermissionInfoName(String expectedName, List<PermissionInfo> permissions) {
528         List<String> names = new ArrayList<String>();
529         for (PermissionInfo permission : permissions) {
530             names.add(permission.name);
531         }
532         boolean isContained = names.contains(expectedName);
533         assertTrue("Permission " + expectedName + " not present in " + names, isContained);
534     }
535 
checkProviderInfoName(String expectedName, List<ProviderInfo> providers)536     private void checkProviderInfoName(String expectedName, List<ProviderInfo> providers) {
537         boolean isContained = false;
538         Iterator<ProviderInfo> infoIterator = providers.iterator();
539         String current;
540         while (infoIterator.hasNext()) {
541             current = infoIterator.next().name;
542             if (current.equals(expectedName)) {
543                 isContained = true;
544                 break;
545             }
546         }
547         assertTrue(isContained);
548     }
549 
checkInstrumentationInfoName(String expectedName, List<InstrumentationInfo> instrumentations)550     private void checkInstrumentationInfoName(String expectedName,
551                                               List<InstrumentationInfo> instrumentations) {
552         boolean isContained = false;
553         Iterator<InstrumentationInfo> infoIterator = instrumentations.iterator();
554         String current;
555         while (infoIterator.hasNext()) {
556             current = infoIterator.next().name;
557             if (current.equals(expectedName)) {
558                 isContained = true;
559                 break;
560             }
561         }
562         assertTrue(isContained);
563     }
564 
565     @Test
testGetInfo()566     public void testGetInfo() throws NameNotFoundException {
567         // Test getApplicationInfo, getText
568         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME,
569                 PackageManager.ApplicationInfoFlags.of(0));
570         int discriptionRes = R.string.hello_android;
571         String expectedDisciptionRes = "Hello, Android!";
572         CharSequence appText = mPackageManager.getText(PACKAGE_NAME, discriptionRes, appInfo);
573         assertEquals(expectedDisciptionRes, appText);
574         ComponentName activityName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME);
575         ComponentName serviceName = new ComponentName(PACKAGE_NAME, SERVICE_NAME);
576         ComponentName receiverName = new ComponentName(PACKAGE_NAME, RECEIVER_NAME);
577         ComponentName instrName = new ComponentName(PACKAGE_NAME, INSTRUMENT_NAME);
578 
579         // Test getPackageInfo
580         PackageInfo packageInfo = mPackageManager.getPackageInfo(PACKAGE_NAME,
581                 PackageManager.PackageInfoFlags.of(GET_INSTRUMENTATION));
582         assertEquals(PACKAGE_NAME, packageInfo.packageName);
583 
584         // Test getApplicationInfo, getApplicationLabel
585         String appLabel = "Android TestCase";
586         assertEquals(appLabel, mPackageManager.getApplicationLabel(appInfo));
587         assertEquals(PACKAGE_NAME, appInfo.processName);
588 
589         // Test getServiceInfo
590         assertEquals(SERVICE_NAME, mPackageManager.getServiceInfo(serviceName,
591                 PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA)).name);
592 
593         // Test getReceiverInfo
594         assertEquals(RECEIVER_NAME, mPackageManager.getReceiverInfo(receiverName,
595                 PackageManager.ComponentInfoFlags.of(0)).name);
596 
597         // Test getPackageArchiveInfo
598         final String apkRoute = mContext.getPackageCodePath();
599         final String apkName = mContext.getPackageName();
600         assertEquals(apkName, mPackageManager.getPackageArchiveInfo(apkRoute,
601                 PackageManager.PackageInfoFlags.of(0)).packageName);
602 
603         // Test getPackagesForUid, getNameForUid
604         checkPackagesNameForUid(PACKAGE_NAME, mPackageManager.getPackagesForUid(appInfo.uid));
605         assertEquals(PACKAGE_NAME, mPackageManager.getNameForUid(appInfo.uid));
606 
607         // Test getActivityInfo
608         assertEquals(ACTIVITY_NAME, mPackageManager.getActivityInfo(activityName,
609                 PackageManager.ComponentInfoFlags.of(0)).name);
610 
611         // Test getPackageGids
612         assertTrue(mPackageManager.getPackageGids(PACKAGE_NAME).length > 0);
613 
614         // Test getPermissionInfo
615         assertEquals(GRANTED_PERMISSION_NAME,
616                 mPackageManager.getPermissionInfo(GRANTED_PERMISSION_NAME, 0).name);
617 
618         // Test getPermissionGroupInfo
619         assertEquals(PERMISSIONGROUP_NAME, mPackageManager.getPermissionGroupInfo(
620                 PERMISSIONGROUP_NAME, 0).name);
621 
622         // Test getAllPermissionGroups
623         List<PermissionGroupInfo> permissionGroups = mPackageManager.getAllPermissionGroups(0);
624         checkPermissionGroupInfoName(PERMISSIONGROUP_NAME, permissionGroups);
625 
626         // Test getInstalledApplications
627         assertTrue(mPackageManager.getInstalledApplications(
628                 PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA)).size() > 0);
629 
630         // Test getInstalledPacakge
631         assertTrue(mPackageManager.getInstalledPackages(
632                 PackageManager.PackageInfoFlags.of(0)).size() > 0);
633 
634         // Test getInstrumentationInfo
635         assertEquals(INSTRUMENT_NAME, mPackageManager.getInstrumentationInfo(instrName, 0).name);
636 
637         // Test getSystemSharedLibraryNames, in javadoc, String array and null
638         // are all OK as return value.
639         mPackageManager.getSystemSharedLibraryNames();
640 
641         // Test getLaunchIntentForPackage, Intent of activity
642         // android.content.pm.cts.TestPmCompare is set to match the condition
643         // to make sure the return of this method is not null.
644         assertEquals(MAIN_ACTION_NAME, mPackageManager.getLaunchIntentForPackage(PACKAGE_NAME)
645                 .getAction());
646 
647         // Test isSafeMode. Because the test case will not run in safe mode, so
648         // the return will be false.
649         assertFalse(mPackageManager.isSafeMode());
650 
651         // Test getTargetSdkVersion
652         int expectedTargetSdk = mPackageManager.getApplicationInfo(PACKAGE_NAME,
653                 PackageManager.ApplicationInfoFlags.of(0)).targetSdkVersion;
654         assertEquals(expectedTargetSdk, mPackageManager.getTargetSdkVersion(PACKAGE_NAME));
655         assertThrows(PackageManager.NameNotFoundException.class,
656                 () -> mPackageManager.getTargetSdkVersion(
657                         "android.content.cts.non_existent_package"));
658     }
659 
checkPackagesNameForUid(String expectedName, String[] uid)660     private void checkPackagesNameForUid(String expectedName, String[] uid) {
661         boolean isContained = false;
662         for (int i = 0; i < uid.length; i++) {
663             if (uid[i].equals(expectedName)) {
664                 isContained = true;
665                 break;
666             }
667         }
668         assertTrue(isContained);
669     }
670 
checkPermissionGroupInfoName(String expectedName, List<PermissionGroupInfo> permissionGroups)671     private void checkPermissionGroupInfoName(String expectedName,
672                                               List<PermissionGroupInfo> permissionGroups) {
673         boolean isContained = false;
674         Iterator<PermissionGroupInfo> infoIterator = permissionGroups.iterator();
675         String current;
676         while (infoIterator.hasNext()) {
677             current = infoIterator.next().name;
678             if (current.equals(expectedName)) {
679                 isContained = true;
680                 break;
681             }
682         }
683         assertTrue(isContained);
684     }
685 
686 
687     /**
688      * Simple test for {@link PackageManager#getPreferredActivities(List, List, String)} that tests
689      * calling it has no effect. The method is essentially a no-op because no preferred activities
690      * can be added.
691      *
692      * @see PackageManager#addPreferredActivity(IntentFilter, int, ComponentName[], ComponentName)
693      */
694     @Test
testGetPreferredActivities()695     public void testGetPreferredActivities() {
696         assertNoPreferredActivities();
697     }
698 
699     /**
700      * Helper method to test that {@link PackageManager#getPreferredActivities(List, List, String)}
701      * returns empty lists.
702      */
assertNoPreferredActivities()703     private void assertNoPreferredActivities() {
704         List<ComponentName> outActivities = new ArrayList<ComponentName>();
705         List<IntentFilter> outFilters = new ArrayList<IntentFilter>();
706         mPackageManager.getPreferredActivities(outFilters, outActivities, PACKAGE_NAME);
707         assertEquals(0, outActivities.size());
708         assertEquals(0, outFilters.size());
709     }
710 
711     /**
712      * Test that calling {@link PackageManager#addPreferredActivity(IntentFilter, int,
713      * ComponentName[], ComponentName)} throws a {@link SecurityException}.
714      * <p/>
715      * The method is protected by the {@link android.permission.SET_PREFERRED_APPLICATIONS}
716      * signature permission. Even though this app declares that permission, it still should not be
717      * able to call this method because it is not signed with the platform certificate.
718      */
719     @Test
testAddPreferredActivity()720     public void testAddPreferredActivity() {
721         IntentFilter intentFilter = new IntentFilter(ACTIVITY_ACTION_NAME);
722         ComponentName[] componentName = {new ComponentName(PACKAGE_NAME, ACTIVITY_NAME)};
723         try {
724             mPackageManager.addPreferredActivity(intentFilter, IntentFilter.MATCH_CATEGORY_HOST,
725                     componentName, componentName[0]);
726             fail("addPreferredActivity unexpectedly succeeded");
727         } catch (SecurityException e) {
728             // expected
729         }
730         assertNoPreferredActivities();
731     }
732 
733     /**
734      * Test that calling {@link PackageManager#clearPackagePreferredActivities(String)} has no
735      * effect.
736      */
737     @Test
testClearPackagePreferredActivities()738     public void testClearPackagePreferredActivities() {
739         // just ensure no unexpected exceptions are thrown, nothing else to do
740         mPackageManager.clearPackagePreferredActivities(PACKAGE_NAME);
741     }
742 
743     @Test
testEnabledSettingAfterUpdate()744     public void testEnabledSettingAfterUpdate() {
745         assertThat(installPackage(LONG_LABEL_NAME_APK)).isTrue();
746 
747         ComponentName compName = new ComponentName(EMPTY_APP_PACKAGE_NAME, EMPTY_APP_ACTIVITY_NAME);
748         SystemUtil.runWithShellPermissionIdentity(() ->
749                 mPackageManager.setComponentEnabledSetting(compName,
750                  COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP));
751         assertEquals(COMPONENT_ENABLED_STATE_ENABLED,
752                 mPackageManager.getComponentEnabledSetting(compName));
753 
754         // Update to the app whose enabled component is removed
755         assertThat(installPackage(EMPTY_APP_APK)).isTrue();
756         assertEquals(COMPONENT_ENABLED_STATE_DEFAULT,
757                 mPackageManager.getComponentEnabledSetting(compName));
758     }
759 
760     @Test
testAccessEnabledSetting()761     public void testAccessEnabledSetting() {
762         mPackageManager.setApplicationEnabledSetting(PACKAGE_NAME,
763                 COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
764         assertEquals(COMPONENT_ENABLED_STATE_ENABLED,
765                 mPackageManager.getApplicationEnabledSetting(PACKAGE_NAME));
766 
767         ComponentName componentName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME);
768         mPackageManager.setComponentEnabledSetting(componentName,
769                 COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
770         assertEquals(COMPONENT_ENABLED_STATE_ENABLED,
771                 mPackageManager.getComponentEnabledSetting(componentName));
772     }
773 
774     @Test
testGetApplicationEnabledSetting_notFound()775     public void testGetApplicationEnabledSetting_notFound() {
776         try {
777             mPackageManager.getApplicationEnabledSetting("this.package.does.not.exist");
778             fail("Exception expected");
779         } catch (IllegalArgumentException expected) {
780         }
781     }
782 
783     @Test
testGetIcon()784     public void testGetIcon() throws NameNotFoundException {
785         assertNotNull(mPackageManager.getApplicationIcon(PACKAGE_NAME));
786         assertNotNull(mPackageManager.getApplicationIcon(mPackageManager.getApplicationInfo(
787                 PACKAGE_NAME, 0)));
788         assertNotNull(mPackageManager
789                 .getActivityIcon(new ComponentName(PACKAGE_NAME, ACTIVITY_NAME)));
790         assertNotNull(mPackageManager.getActivityIcon(new Intent(MAIN_ACTION_NAME)));
791 
792         assertNotNull(mPackageManager.getDefaultActivityIcon());
793         assertTrue(mPackageManager.isDefaultApplicationIcon(
794                 mPackageManager.getDefaultActivityIcon()));
795         assertTrue(mPackageManager.isDefaultApplicationIcon(mPackageManager.getDefaultActivityIcon()
796                 .getConstantState().newDrawable()));
797 
798         assertFalse(mPackageManager.isDefaultApplicationIcon(mPackageManager.getActivityIcon(
799                 new ComponentName(PACKAGE_NAME, ACTIVITY_NAME))));
800 
801         // getDrawable is called by ComponentInfo.loadIcon() which called by getActivityIcon()
802         // method of PackageMaganer. Here is just assurance for its functionality.
803         int iconRes = R.drawable.start;
804         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME,
805                 PackageManager.ApplicationInfoFlags.of(0));
806         assertNotNull(mPackageManager.getDrawable(PACKAGE_NAME, iconRes, appInfo));
807     }
808 
809     @Test
testCheckSignaturesMatch_byPackageName()810     public void testCheckSignaturesMatch_byPackageName() {
811         // Compare the signature of this package to another package installed by this test suite
812         // (see AndroidTest.xml). Their signatures must match.
813         assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(PACKAGE_NAME,
814                 "com.android.cts.stub"));
815         // This package's signature should match its own signature.
816         assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(PACKAGE_NAME,
817                 PACKAGE_NAME));
818     }
819 
820     @Test
testCheckSignaturesMatch_byUid()821     public void testCheckSignaturesMatch_byUid() throws NameNotFoundException {
822         // Compare the signature of this package to another package installed by this test suite
823         // (see AndroidTest.xml). Their signatures must match.
824         int uid1 = mPackageManager.getPackageInfo(PACKAGE_NAME,
825                 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid;
826         int uid2 = mPackageManager.getPackageInfo("com.android.cts.stub",
827                 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid;
828         assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(uid1, uid2));
829 
830         // A UID's signature should match its own signature.
831         assertEquals(PackageManager.SIGNATURE_MATCH, mPackageManager.checkSignatures(uid1, uid1));
832     }
833 
834     @Test
testCheckSignaturesNoMatch_byPackageName()835     public void testCheckSignaturesNoMatch_byPackageName() {
836         // This test package's signature shouldn't match the system's signature.
837         assertEquals(PackageManager.SIGNATURE_NO_MATCH, mPackageManager.checkSignatures(
838                 PACKAGE_NAME, "android"));
839     }
840 
841     @Test
testCheckSignaturesNoMatch_byUid()842     public void testCheckSignaturesNoMatch_byUid() throws NameNotFoundException {
843         // This test package's signature shouldn't match the system's signature.
844         int uid1 = mPackageManager.getPackageInfo(PACKAGE_NAME,
845                 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid;
846         int uid2 = mPackageManager.getPackageInfo("android",
847                 PackageManager.PackageInfoFlags.of(0)).applicationInfo.uid;
848         assertEquals(PackageManager.SIGNATURE_NO_MATCH,
849                 mPackageManager.checkSignatures(uid1, uid2));
850     }
851 
852     @Test
testCheckSignaturesUnknownPackage()853     public void testCheckSignaturesUnknownPackage() {
854         assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, mPackageManager.checkSignatures(
855                 PACKAGE_NAME, "this.package.does.not.exist"));
856     }
857 
858     @Test
testCheckPermissionGranted()859     public void testCheckPermissionGranted() {
860         assertEquals(PackageManager.PERMISSION_GRANTED,
861                 mPackageManager.checkPermission(GRANTED_PERMISSION_NAME, PACKAGE_NAME));
862     }
863 
864     @Test
testCheckPermissionNotGranted()865     public void testCheckPermissionNotGranted() {
866         assertEquals(PackageManager.PERMISSION_DENIED,
867                 mPackageManager.checkPermission(NOT_GRANTED_PERMISSION_NAME, PACKAGE_NAME));
868     }
869 
870     @Test
testResolveMethods()871     public void testResolveMethods() {
872         // Test resolveActivity
873         Intent intent = new Intent(ACTIVITY_ACTION_NAME);
874         intent.setComponent(new ComponentName(PACKAGE_NAME, ACTIVITY_NAME));
875         assertEquals(ACTIVITY_NAME, mPackageManager.resolveActivity(intent,
876                 PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY))
877                 .activityInfo.name);
878 
879         // Test resolveService
880         intent = new Intent(SERVICE_ACTION_NAME);
881         intent.setComponent(new ComponentName(PACKAGE_NAME, SERVICE_NAME));
882         ResolveInfo resolveInfo = mPackageManager.resolveService(intent,
883                 PackageManager.ResolveInfoFlags.of(0));
884         assertEquals(SERVICE_NAME, resolveInfo.serviceInfo.name);
885 
886         // Test resolveContentProvider
887         String providerAuthorities = "ctstest";
888         assertEquals(PROVIDER_NAME,
889                 mPackageManager.resolveContentProvider(providerAuthorities,
890                         PackageManager.ComponentInfoFlags.of(0)).name);
891     }
892 
893     @Test
testGetResources()894     public void testGetResources() throws NameNotFoundException {
895         ComponentName componentName = new ComponentName(PACKAGE_NAME, ACTIVITY_NAME);
896         int resourceId = R.xml.pm_test;
897         String xmlName = "android.content.cts:xml/pm_test";
898         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME,
899                 PackageManager.ApplicationInfoFlags.of(0));
900         assertNotNull(mPackageManager.getXml(PACKAGE_NAME, resourceId, appInfo));
901         assertEquals(xmlName, mPackageManager.getResourcesForActivity(componentName)
902                 .getResourceName(resourceId));
903         assertEquals(xmlName, mPackageManager.getResourcesForApplication(appInfo).getResourceName(
904                 resourceId));
905         assertEquals(xmlName, mPackageManager.getResourcesForApplication(PACKAGE_NAME)
906                 .getResourceName(resourceId));
907     }
908 
909     @Test
testGetResources_withConfig()910     public void testGetResources_withConfig() throws NameNotFoundException {
911         int resourceId = R.string.config_overridden_string;
912         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME,
913                 PackageManager.ApplicationInfoFlags.of(0));
914 
915         Configuration c1 = new Configuration(mContext.getResources().getConfiguration());
916         c1.orientation = Configuration.ORIENTATION_PORTRAIT;
917         assertEquals("default", mPackageManager.getResourcesForApplication(
918                 appInfo, c1).getString(resourceId));
919 
920         Configuration c2 = new Configuration(mContext.getResources().getConfiguration());
921         c2.orientation = Configuration.ORIENTATION_LANDSCAPE;
922         assertEquals("landscape", mPackageManager.getResourcesForApplication(
923                 appInfo, c2).getString(resourceId));
924     }
925 
926     @Test
testGetPackageArchiveInfo()927     public void testGetPackageArchiveInfo() {
928         final String apkPath = mContext.getPackageCodePath();
929         final String apkName = mContext.getPackageName();
930 
931         PackageInfo pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
932                 PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES));
933         assertEquals("getPackageArchiveInfo should return the correct package name",
934                 apkName, pkgInfo.packageName);
935         assertNotNull("SigningInfo should have been collected when GET_SIGNING_CERTIFICATES"
936                 + " flag is specified", pkgInfo.signingInfo);
937 
938         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
939                 PackageManager.PackageInfoFlags.of(GET_SIGNATURES));
940         assertNotNull("Signatures should have been collected when GET_SIGNATURES"
941                 + " flag is specified", pkgInfo.signatures);
942 
943         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
944                 PackageManager.PackageInfoFlags.of(
945                         GET_SIGNATURES | PackageManager.GET_SIGNING_CERTIFICATES));
946         assertNotNull("SigningInfo should have been collected when"
947                         + " GET_SIGNATURES and GET_SIGNING_CERTIFICATES flags are both specified",
948                 pkgInfo.signingInfo);
949         assertNotNull("Signatures should have been collected when"
950                         + " GET_SIGNATURES and GET_SIGNING_CERTIFICATES flags are both specified",
951                 pkgInfo.signatures);
952 
953         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
954                 PackageManager.PackageInfoFlags.of(GET_ACTIVITIES));
955         assertNotNull("Activities should have been collected when GET_ACTIVITIES"
956                 + " flag is specified", pkgInfo.activities);
957 
958         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
959                 PackageManager.PackageInfoFlags.of(GET_PROVIDERS));
960         assertNotNull("Providers should have been collected when GET_PROVIDERS"
961                 + " flag is specified", pkgInfo.providers);
962 
963         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
964                 PackageManager.PackageInfoFlags.of(GET_SERVICES));
965         assertNotNull("Services should have been collected when GET_SERVICES"
966                 + " flag is specified", pkgInfo.services);
967 
968         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
969                 PackageManager.PackageInfoFlags.of(GET_INSTRUMENTATION));
970         assertNotNull("Instrumentation should have been collected when GET_INSTRUMENTATION"
971                 + " flag is specified", pkgInfo.instrumentation);
972 
973         pkgInfo = mPackageManager.getPackageArchiveInfo(apkPath,
974                 PackageManager.PackageInfoFlags.of(GET_PERMISSIONS));
975         assertNotNull("Permissions should have been collected when GET_PERMISSIONS"
976                 + " flag is specified", pkgInfo.permissions);
977     }
978 
runTestGetPackageArchiveInfoSameApplicationInfo(long flags)979     private void runTestGetPackageArchiveInfoSameApplicationInfo(long flags) {
980         final String apkPath = mContext.getPackageCodePath();
981         PackageInfo packageInfo = mPackageManager.getPackageArchiveInfo(apkPath,
982                 PackageManager.PackageInfoFlags.of(flags));
983 
984         ApplicationInfo applicationInfo = null;
985         if (packageInfo.activities != null) {
986             for (ActivityInfo ac : packageInfo.activities) {
987                 if (applicationInfo == null) {
988                     applicationInfo = ac.applicationInfo;
989                 } else {
990                     assertSame(applicationInfo, ac.applicationInfo);
991                 }
992             }
993         }
994         if (packageInfo.receivers != null) {
995             for (ActivityInfo ac : packageInfo.receivers) {
996                 if (applicationInfo == null) {
997                     applicationInfo = ac.applicationInfo;
998                 } else {
999                     assertSame(applicationInfo, ac.applicationInfo);
1000                 }
1001             }
1002         }
1003         if (packageInfo.services != null) {
1004             for (ServiceInfo si : packageInfo.services) {
1005                 if (applicationInfo == null) {
1006                     applicationInfo = si.applicationInfo;
1007                 } else {
1008                     assertSame(applicationInfo, si.applicationInfo);
1009                 }
1010             }
1011         }
1012         if (packageInfo.providers != null) {
1013             for (ProviderInfo pi : packageInfo.providers) {
1014                 if (applicationInfo == null) {
1015                     applicationInfo = pi.applicationInfo;
1016                 } else {
1017                     assertSame(applicationInfo, pi.applicationInfo);
1018                 }
1019             }
1020         }
1021     }
1022 
1023     @Test
testGetPackageArchiveInfoSameApplicationInfo()1024     public void testGetPackageArchiveInfoSameApplicationInfo() {
1025         runTestGetPackageArchiveInfoSameApplicationInfo(PackageManager.GET_META_DATA);
1026         runTestGetPackageArchiveInfoSameApplicationInfo(
1027                 PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES);
1028         runTestGetPackageArchiveInfoSameApplicationInfo(
1029                 PackageManager.GET_META_DATA | PackageManager.GET_RECEIVERS);
1030         runTestGetPackageArchiveInfoSameApplicationInfo(
1031                 PackageManager.GET_META_DATA | PackageManager.GET_SERVICES);
1032         runTestGetPackageArchiveInfoSameApplicationInfo(
1033                 PackageManager.GET_META_DATA | PackageManager.GET_PROVIDERS);
1034         runTestGetPackageArchiveInfoSameApplicationInfo(
1035                 PackageManager.GET_META_DATA | PackageManager.GET_ACTIVITIES
1036                         | PackageManager.GET_RECEIVERS);
1037     }
1038 
1039     @Test
testGetNamesForUids_null()1040     public void testGetNamesForUids_null() throws Exception {
1041         assertNull(mPackageManager.getNamesForUids(null));
1042     }
1043 
1044     @Test
testGetNamesForUids_empty()1045     public void testGetNamesForUids_empty() throws Exception {
1046         assertNull(mPackageManager.getNamesForUids(new int[0]));
1047     }
1048 
1049     @Test
testGetNamesForUids_valid()1050     public void testGetNamesForUids_valid() throws Exception {
1051         final int shimId =
1052                 mPackageManager.getApplicationInfo(CTS_SHIM_PACKAGE_NAME,
1053                         PackageManager.ApplicationInfoFlags.of(0)).uid;
1054         final int[] uids = new int[]{
1055                 1000,
1056                 Integer.MAX_VALUE,
1057                 shimId,
1058         };
1059         final String[] result;
1060         result = mPackageManager.getNamesForUids(uids);
1061         assertNotNull(result);
1062         assertEquals(3, result.length);
1063         assertEquals("shared:android.uid.system", result[0]);
1064         assertEquals(null, result[1]);
1065         assertEquals("shared:com.android.cts.ctsshim", result[2]);
1066     }
1067 
1068     @Test
testGetPackageUid()1069     public void testGetPackageUid() throws NameNotFoundException {
1070         int userId = mContext.getUserId();
1071         int expectedUid = UserHandle.getUid(userId, 1000);
1072 
1073         assertEquals(expectedUid, mPackageManager.getPackageUid("android",
1074                 PackageManager.PackageInfoFlags.of(0)));
1075 
1076         int uid = mPackageManager.getApplicationInfo(CTS_SHIM_PACKAGE_NAME,
1077                 PackageManager.ApplicationInfoFlags.of(0)).uid;
1078         assertEquals(uid, mPackageManager.getPackageUid(CTS_SHIM_PACKAGE_NAME,
1079                 PackageManager.PackageInfoFlags.of(0)));
1080     }
1081 
1082     @Test
testGetPackageInfo()1083     public void testGetPackageInfo() throws NameNotFoundException {
1084         PackageInfo pkgInfo = mPackageManager.getPackageInfo(PACKAGE_NAME, GET_META_DATA
1085                 | GET_PERMISSIONS | GET_ACTIVITIES | GET_PROVIDERS | GET_SERVICES | GET_RECEIVERS);
1086         assertTestPackageInfo(pkgInfo);
1087     }
1088 
1089     @Test
testPackageSettingsFlags()1090     public void testPackageSettingsFlags() throws Exception {
1091         assertEquals("Success\n", SystemUtil.runShellCommand(
1092                 "pm install -t " + HELLO_WORLD_LOTS_OF_FLAGS_APK));
1093         final String pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, "    pkgFlags=[");
1094         assertEquals(
1095                 " DEBUGGABLE HAS_CODE ALLOW_TASK_REPARENTING ALLOW_CLEAR_USER_DATA TEST_ONLY "
1096                         + "VM_SAFE_MODE ALLOW_BACKUP LARGE_HEAP ]",
1097                 pkgFlags);
1098         final String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
1099                 "    privatePkgFlags=[");
1100         assertEquals(
1101                 " PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION "
1102                         + "ALLOW_AUDIO_PLAYBACK_CAPTURE "
1103                         + "PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING ]",
1104                 privatePkgFlags);
1105     }
1106 
1107     @Test
testGetPackageInfo_notFound()1108     public void testGetPackageInfo_notFound() {
1109         try {
1110             mPackageManager.getPackageInfo("this.package.does.not.exist",
1111                     PackageManager.PackageInfoFlags.of(0));
1112             fail("Exception expected");
1113         } catch (NameNotFoundException expected) {
1114         }
1115     }
1116 
1117     @Test
testGetInstalledPackages()1118     public void testGetInstalledPackages() throws Exception {
1119         List<PackageInfo> pkgs = mPackageManager.getInstalledPackages(
1120                 PackageManager.PackageInfoFlags.of(
1121                         GET_META_DATA | GET_PERMISSIONS | GET_ACTIVITIES | GET_PROVIDERS
1122                                 | GET_SERVICES | GET_RECEIVERS));
1123 
1124         PackageInfo pkgInfo = findPackageOrFail(pkgs, PACKAGE_NAME);
1125         assertTestPackageInfo(pkgInfo);
1126     }
1127 
1128     /**
1129      * Asserts that the pkgInfo object correctly describes the {@link #PACKAGE_NAME} package.
1130      */
assertTestPackageInfo(PackageInfo pkgInfo)1131     private void assertTestPackageInfo(PackageInfo pkgInfo) {
1132         // Check metadata
1133         ApplicationInfo appInfo = pkgInfo.applicationInfo;
1134         assertEquals(APPLICATION_NAME, appInfo.name);
1135         assertEquals("Android TestCase", appInfo.loadLabel(mPackageManager));
1136         assertEquals(PACKAGE_NAME, appInfo.packageName);
1137         assertTrue(appInfo.enabled);
1138         // The process name defaults to the package name when not set.
1139         assertEquals(PACKAGE_NAME, appInfo.processName);
1140         assertEquals(0, appInfo.flags & FLAG_SYSTEM);
1141         assertEquals(FLAG_INSTALLED, appInfo.flags & FLAG_INSTALLED);
1142         assertEquals(FLAG_HAS_CODE, appInfo.flags & FLAG_HAS_CODE);
1143 
1144         // Check required permissions
1145         List<String> requestedPermissions = Arrays.asList(pkgInfo.requestedPermissions);
1146         assertThat(requestedPermissions).containsAtLeast(
1147                 "android.permission.MANAGE_ACCOUNTS",
1148                 "android.permission.ACCESS_NETWORK_STATE",
1149                 "android.content.cts.permission.TEST_GRANTED");
1150 
1151         // Check usesPermissionFlags
1152         boolean requestedAccessFineLocation = false;
1153         boolean requestedAccessCoarseLocation = false;
1154         for (int i = 0; i < pkgInfo.requestedPermissions.length; i++) {
1155             final String name = pkgInfo.requestedPermissions[i];
1156             final int flags = pkgInfo.requestedPermissionsFlags[i];
1157 
1158             // Verify "never for location" flag
1159             final boolean neverForLocation = (flags
1160                     & PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION) != 0;
1161             if ("android.content.cts.permission.TEST_GRANTED".equals(name)) {
1162                 assertTrue(name + " with flags " + flags, neverForLocation);
1163             } else {
1164                 assertFalse(name + " with flags " + flags, neverForLocation);
1165             }
1166 
1167             // Verify "implicit" flag
1168             final boolean hasImplicitFlag =
1169                     (flags & PackageInfo.REQUESTED_PERMISSION_IMPLICIT) != 0;
1170             if ("android.permission.ACCESS_FINE_LOCATION".equals(name)) {
1171                 assertFalse(name + " with flags " + flags, hasImplicitFlag);
1172                 requestedAccessFineLocation = true;
1173             }
1174             if ("android.permission.ACCESS_COARSE_LOCATION".equals(name)) {
1175                 assertTrue(name + " with flags " + flags, hasImplicitFlag);
1176                 requestedAccessCoarseLocation = true;
1177             }
1178         }
1179         assertTrue("expected ACCESS_FINE_LOCATION to be requested", requestedAccessFineLocation);
1180         assertTrue("expected ACCESS_COARSE_LOCATION to be requested",
1181                 requestedAccessCoarseLocation);
1182 
1183         // Check declared permissions
1184         PermissionInfo declaredPermission = (PermissionInfo) findPackageItemOrFail(
1185                 pkgInfo.permissions, CALL_ABROAD_PERMISSION_NAME);
1186         assertEquals("Call abroad", declaredPermission.loadLabel(mPackageManager));
1187         assertEquals(PERMISSIONGROUP_NAME, declaredPermission.group);
1188         assertEquals(PermissionInfo.PROTECTION_NORMAL, declaredPermission.protectionLevel);
1189 
1190         // Check if number of activities in PackageInfo matches number of activities in manifest,
1191         // to make sure no synthesized activities not in the manifest are returned.
1192         assertEquals("Number of activities in manifest != Number of activities in PackageInfo",
1193                 NUM_OF_ACTIVITIES_IN_MANIFEST, pkgInfo.activities.length);
1194         // Check activities
1195         ActivityInfo activity = findPackageItemOrFail(pkgInfo.activities, ACTIVITY_NAME);
1196         assertTrue(activity.enabled);
1197         assertTrue(activity.exported); // Has intent filters - export by default.
1198         assertEquals(PACKAGE_NAME, activity.taskAffinity);
1199         assertEquals(ActivityInfo.LAUNCH_SINGLE_TOP, activity.launchMode);
1200 
1201         // Check services
1202         ServiceInfo service = findPackageItemOrFail(pkgInfo.services, SERVICE_NAME);
1203         assertTrue(service.enabled);
1204         assertTrue(service.exported); // Has intent filters - export by default.
1205         assertEquals(PACKAGE_NAME, service.packageName);
1206         assertEquals(CALL_ABROAD_PERMISSION_NAME, service.permission);
1207 
1208         // Check ContentProviders
1209         ProviderInfo provider = findPackageItemOrFail(pkgInfo.providers, PROVIDER_NAME);
1210         assertTrue(provider.enabled);
1211         assertEquals(PACKAGE_NAME, provider.packageName);
1212         assertEquals("ctstest", provider.authority);
1213         ProviderInfo nonExportedProvider =
1214                 findPackageItemOrFail(pkgInfo.providers, "android.content.cts.MockBuggyProvider");
1215         assertFalse(nonExportedProvider.exported); // Don't export by default.
1216 
1217         // Check Receivers
1218         ActivityInfo receiver = findPackageItemOrFail(pkgInfo.receivers, RECEIVER_NAME);
1219         assertTrue(receiver.enabled);
1220         assertTrue(receiver.exported); // Has intent filters - export by default.
1221         assertEquals(PACKAGE_NAME, receiver.packageName);
1222     }
1223 
1224     // Tests that other packages can be queried.
1225     @Test
testGetInstalledPackages_OtherPackages()1226     public void testGetInstalledPackages_OtherPackages() throws Exception {
1227         List<PackageInfo> pkgInfos = mPackageManager.getInstalledPackages(
1228                 PackageManager.PackageInfoFlags.of(0));
1229 
1230         // Check a normal package.
1231         PackageInfo pkgInfo = findPackageOrFail(pkgInfos, "com.android.cts.stub"); // A test package
1232         assertEquals(0, pkgInfo.applicationInfo.flags & FLAG_SYSTEM);
1233 
1234         // Check a system package.
1235         pkgInfo = findPackageOrFail(pkgInfos, "android");
1236         assertEquals(FLAG_SYSTEM, pkgInfo.applicationInfo.flags & FLAG_SYSTEM);
1237     }
1238 
1239     @Test
testGetInstalledApplications()1240     public void testGetInstalledApplications() throws Exception {
1241         List<ApplicationInfo> apps = mPackageManager.getInstalledApplications(
1242                 PackageManager.ApplicationInfoFlags.of(GET_META_DATA));
1243 
1244         ApplicationInfo app = findPackageItemOrFail(
1245                 apps.toArray(new ApplicationInfo[]{}), APPLICATION_NAME);
1246 
1247         assertEquals(APPLICATION_NAME, app.name);
1248         assertEquals("Android TestCase", app.loadLabel(mPackageManager));
1249         assertEquals(PACKAGE_NAME, app.packageName);
1250         assertTrue(app.enabled);
1251         // The process name defaults to the package name when not set.
1252         assertEquals(PACKAGE_NAME, app.processName);
1253     }
1254 
findPackageOrFail(List<PackageInfo> pkgInfos, String pkgName)1255     private PackageInfo findPackageOrFail(List<PackageInfo> pkgInfos, String pkgName) {
1256         for (PackageInfo pkgInfo : pkgInfos) {
1257             if (pkgName.equals(pkgInfo.packageName)) {
1258                 return pkgInfo;
1259             }
1260         }
1261         fail("Package not found with name " + pkgName);
1262         return null;
1263     }
1264 
findPackageItemOrFail(T[] items, String name)1265     private <T extends PackageItemInfo> T findPackageItemOrFail(T[] items, String name) {
1266         for (T item : items) {
1267             if (name.equals(item.name)) {
1268                 return item;
1269             }
1270         }
1271         fail("Package item not found with name " + name);
1272         return null;
1273     }
1274 
1275     @Test
testGetPackagesHoldingPermissions()1276     public void testGetPackagesHoldingPermissions() {
1277         List<PackageInfo> pkgInfos = mPackageManager.getPackagesHoldingPermissions(
1278                 new String[]{GRANTED_PERMISSION_NAME}, PackageManager.PackageInfoFlags.of(0));
1279         findPackageOrFail(pkgInfos, PACKAGE_NAME);
1280 
1281         pkgInfos = mPackageManager.getPackagesHoldingPermissions(
1282                 new String[]{NOT_GRANTED_PERMISSION_NAME},
1283                 PackageManager.PackageInfoFlags.of(0));
1284         for (PackageInfo pkgInfo : pkgInfos) {
1285             if (PACKAGE_NAME.equals(pkgInfo.packageName)) {
1286                 fail("Must not return package " + PACKAGE_NAME);
1287             }
1288         }
1289     }
1290 
1291     @Test
testGetPermissionInfo()1292     public void testGetPermissionInfo() throws NameNotFoundException {
1293         // Check a normal permission.
1294         String permissionName = "android.permission.INTERNET";
1295         PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0);
1296         assertEquals(permissionName, permissionInfo.name);
1297         assertEquals(PermissionInfo.PROTECTION_NORMAL, permissionInfo.getProtection());
1298 
1299         // Check a dangerous (runtime) permission.
1300         permissionName = "android.permission.RECORD_AUDIO";
1301         permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0);
1302         assertEquals(permissionName, permissionInfo.name);
1303         assertEquals(PermissionInfo.PROTECTION_DANGEROUS, permissionInfo.getProtection());
1304         assertNotNull(permissionInfo.group);
1305 
1306         // Check a signature permission.
1307         permissionName = "android.permission.MODIFY_PHONE_STATE";
1308         permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0);
1309         assertEquals(permissionName, permissionInfo.name);
1310         assertEquals(PermissionInfo.PROTECTION_SIGNATURE, permissionInfo.getProtection());
1311 
1312         // Check a special access (appop) permission.
1313         permissionName = "android.permission.SYSTEM_ALERT_WINDOW";
1314         permissionInfo = mPackageManager.getPermissionInfo(permissionName, 0);
1315         assertEquals(permissionName, permissionInfo.name);
1316         assertEquals(PermissionInfo.PROTECTION_SIGNATURE, permissionInfo.getProtection());
1317         assertEquals(PermissionInfo.PROTECTION_FLAG_APPOP,
1318                 permissionInfo.getProtectionFlags() & PermissionInfo.PROTECTION_FLAG_APPOP);
1319     }
1320 
1321     @Test
testGetPermissionInfo_notFound()1322     public void testGetPermissionInfo_notFound() {
1323         try {
1324             mPackageManager.getPermissionInfo("android.permission.nonexistent.permission", 0);
1325             fail("Exception expected");
1326         } catch (NameNotFoundException expected) {
1327         }
1328     }
1329 
1330     @Test
testGetPermissionGroupInfo()1331     public void testGetPermissionGroupInfo() throws NameNotFoundException {
1332         PermissionGroupInfo groupInfo = mPackageManager.getPermissionGroupInfo(
1333                 PERMISSIONGROUP_NAME, 0);
1334         assertEquals(PERMISSIONGROUP_NAME, groupInfo.name);
1335         assertEquals(PACKAGE_NAME, groupInfo.packageName);
1336         assertFalse(TextUtils.isEmpty(groupInfo.loadDescription(mPackageManager)));
1337     }
1338 
1339     @Test
testGetPermissionGroupInfo_notFound()1340     public void testGetPermissionGroupInfo_notFound() throws NameNotFoundException {
1341         try {
1342             mPackageManager.getPermissionGroupInfo("this.group.does.not.exist", 0);
1343             fail("Exception expected");
1344         } catch (NameNotFoundException expected) {
1345         }
1346     }
1347 
1348     @Test
testAddPermission_cantAddOutsideRoot()1349     public void testAddPermission_cantAddOutsideRoot() {
1350         PermissionInfo permissionInfo = new PermissionInfo();
1351         permissionInfo.name = "some.other.permission.tree.some-permission";
1352         permissionInfo.nonLocalizedLabel = "Some Permission";
1353         permissionInfo.protectionLevel = PermissionInfo.PROTECTION_NORMAL;
1354         // Remove first
1355         try {
1356             mPackageManager.removePermission(permissionInfo.name);
1357         } catch (SecurityException se) {
1358         }
1359         try {
1360             mPackageManager.addPermission(permissionInfo);
1361             fail("Must not add permission outside the permission tree defined in the manifest.");
1362         } catch (SecurityException expected) {
1363         }
1364     }
1365 
1366     @Test
testAddPermission()1367     public void testAddPermission() throws NameNotFoundException {
1368         PermissionInfo permissionInfo = new PermissionInfo();
1369         permissionInfo.name = PERMISSION_TREE_ROOT + ".some-permission";
1370         permissionInfo.protectionLevel = PermissionInfo.PROTECTION_NORMAL;
1371         permissionInfo.nonLocalizedLabel = "Some Permission";
1372         // Remove first
1373         try {
1374             mPackageManager.removePermission(permissionInfo.name);
1375         } catch (SecurityException se) {
1376         }
1377         mPackageManager.addPermission(permissionInfo);
1378         PermissionInfo savedInfo = mPackageManager.getPermissionInfo(permissionInfo.name, 0);
1379         assertEquals(PACKAGE_NAME, savedInfo.packageName);
1380         assertEquals(PermissionInfo.PROTECTION_NORMAL, savedInfo.protectionLevel);
1381     }
1382 
1383     @Test
testSetSystemAppHiddenUntilInstalled()1384     public void testSetSystemAppHiddenUntilInstalled() throws Exception {
1385         String packageToManipulate = CTS_SHIM_PACKAGE_NAME;
1386         try {
1387             mPackageManager.getPackageInfo(packageToManipulate, MATCH_SYSTEM_ONLY);
1388         } catch (NameNotFoundException e) {
1389             Log.i(TAG, "Device doesn't have " + packageToManipulate + " installed, skipping");
1390             return;
1391         }
1392 
1393         try {
1394             SystemUtil.runWithShellPermissionIdentity(() ->
1395                     mPackageManager.setSystemAppState(packageToManipulate,
1396                             PackageManager.SYSTEM_APP_STATE_UNINSTALLED));
1397             SystemUtil.runWithShellPermissionIdentity(() ->
1398                     mPackageManager.setSystemAppState(packageToManipulate,
1399                             SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN));
1400 
1401             // Setting the state to SYSTEM_APP_STATE_UNINSTALLED is an async operation in
1402             // PackageManagerService with no way to listen for completion, so poll until the
1403             // app is no longer found.
1404             int pollingPeriodMs = 100;
1405             int timeoutMs = 1000;
1406             long startTimeMs = SystemClock.elapsedRealtime();
1407             boolean isAppStillVisible = true;
1408             while (SystemClock.elapsedRealtime() < startTimeMs + timeoutMs) {
1409                 try {
1410                     mPackageManager.getPackageInfo(packageToManipulate,
1411                             PackageManager.PackageInfoFlags.of(MATCH_SYSTEM_ONLY));
1412                 } catch (NameNotFoundException e) {
1413                     // expected, stop polling
1414                     isAppStillVisible = false;
1415                     break;
1416                 }
1417                 Thread.sleep(pollingPeriodMs);
1418             }
1419             if (isAppStillVisible) {
1420                 fail(packageToManipulate + " should not be found via getPackageInfo.");
1421             }
1422         } finally {
1423             SystemUtil.runWithShellPermissionIdentity(() ->
1424                     mPackageManager.setSystemAppState(packageToManipulate,
1425                             PackageManager.SYSTEM_APP_STATE_INSTALLED));
1426             SystemUtil.runWithShellPermissionIdentity(() ->
1427                     mPackageManager.setSystemAppState(packageToManipulate,
1428                             PackageManager.SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE));
1429             try {
1430                 mPackageManager.getPackageInfo(packageToManipulate,
1431                         PackageManager.PackageInfoFlags.of(MATCH_SYSTEM_ONLY));
1432             } catch (NameNotFoundException e) {
1433                 fail(packageToManipulate
1434                         + " should be found via getPackageInfo after re-enabling.");
1435             }
1436         }
1437     }
1438 
1439     @Test
testGetPackageInfo_ApexSupported_ApexPackage_MatchesApex()1440     public void testGetPackageInfo_ApexSupported_ApexPackage_MatchesApex() throws Exception {
1441         final int flags = PackageManager.MATCH_APEX
1442                 | PackageManager.MATCH_FACTORY_ONLY
1443                 | PackageManager.GET_SIGNING_CERTIFICATES
1444                 | GET_SIGNATURES;
1445         PackageInfo packageInfo = mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME,
1446                 PackageManager.PackageInfoFlags.of(flags));
1447         assertShimApexInfoIsCorrect(packageInfo);
1448     }
1449 
1450     @Test
testGetPackageInfo_ApexSupported_ApexPackage_DoesNotMatchApex()1451     public void testGetPackageInfo_ApexSupported_ApexPackage_DoesNotMatchApex() {
1452         try {
1453             mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME,
1454                     PackageManager.PackageInfoFlags.of(0));
1455             fail("NameNotFoundException expected");
1456         } catch (NameNotFoundException expected) {
1457         }
1458     }
1459 
1460     @Test
testGetInstalledPackages_ApexSupported_MatchesApex()1461     public void testGetInstalledPackages_ApexSupported_MatchesApex() {
1462         final int flags = PackageManager.MATCH_APEX
1463                 | PackageManager.MATCH_FACTORY_ONLY
1464                 | PackageManager.GET_SIGNING_CERTIFICATES
1465                 | GET_SIGNATURES;
1466         List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(
1467                 PackageManager.PackageInfoFlags.of(flags));
1468         List<PackageInfo> shimApex = installedPackages.stream().filter(
1469                 packageInfo -> packageInfo.packageName.equals(SHIM_APEX_PACKAGE_NAME)).collect(
1470                 Collectors.toList());
1471         assertWithMessage("More than one shim apex found").that(shimApex).hasSize(1);
1472         assertShimApexInfoIsCorrect(shimApex.get(0));
1473     }
1474 
1475     @Test
testGetInstalledPackages_ApexSupported_DoesNotMatchApex()1476     public void testGetInstalledPackages_ApexSupported_DoesNotMatchApex() {
1477         List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(
1478                 PackageManager.PackageInfoFlags.of(0));
1479         List<PackageInfo> shimApex = installedPackages.stream().filter(
1480                 packageInfo -> packageInfo.packageName.equals(SHIM_APEX_PACKAGE_NAME)).collect(
1481                 Collectors.toList());
1482         assertWithMessage("Shim apex wasn't supposed to be found").that(shimApex).isEmpty();
1483     }
1484 
1485     @Test
1486     @RequiresFlagsEnabled(FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
testGetPackageInfo_apex_hasApexPackageName()1487     public void testGetPackageInfo_apex_hasApexPackageName() throws Exception {
1488         PackageInfo packageInfo =
1489                 mPackageManager.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
1490 
1491         assertThat(packageInfo.packageName).isEqualTo(SHIM_APEX_PACKAGE_NAME);
1492         assertThat(packageInfo.getApexPackageName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
1493     }
1494 
1495     @Test
1496     @RequiresFlagsEnabled(FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
testGetPackageInfo_apkInApex_hasApexPackageName()1497     public void testGetPackageInfo_apkInApex_hasApexPackageName()
1498             throws Exception {
1499         PackageInfo packageInfo =
1500                 mPackageManager.getPackageInfo(CTS_SHIM_PACKAGE_NAME, /* flags= */ 0);
1501 
1502         assertThat(packageInfo.packageName).isEqualTo(CTS_SHIM_PACKAGE_NAME);
1503         assertThat(packageInfo.getApexPackageName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
1504     }
1505 
1506     @Test
1507     @RequiresFlagsEnabled(FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
testGetPackageInfo_normalApk_noApexPackageName()1508     public void testGetPackageInfo_normalApk_noApexPackageName() throws Exception {
1509         PackageInfo packageInfo =
1510                 mPackageManager.getPackageInfo(PACKAGE_NAME, /* flags= */ 0);
1511 
1512         assertThat(packageInfo.packageName).isEqualTo(PACKAGE_NAME);
1513         assertThat(packageInfo.getApexPackageName()).isNull();
1514     }
1515 
1516     /**
1517      * Test that {@link ComponentInfo#metaData} data associated with all components in this
1518      * package will only be filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1519      */
1520     @Test
testGetInfo_noMetaData_InPackage()1521     public void testGetInfo_noMetaData_InPackage() throws Exception {
1522         final PackageInfo info = mPackageManager.getPackageInfo(PACKAGE_NAME,
1523                 PackageManager.PackageInfoFlags.of(
1524                         GET_ACTIVITIES | GET_SERVICES | GET_RECEIVERS | GET_PROVIDERS));
1525 
1526         assertThat(info.applicationInfo.metaData).isNull();
1527         Arrays.stream(info.activities).forEach(i -> assertThat(i.metaData).isNull());
1528         Arrays.stream(info.services).forEach(i -> assertThat(i.metaData).isNull());
1529         Arrays.stream(info.receivers).forEach(i -> assertThat(i.metaData).isNull());
1530         Arrays.stream(info.providers).forEach(i -> assertThat(i.metaData).isNull());
1531     }
1532 
1533     /**
1534      * Test that {@link ComponentInfo#metaData} data associated with this application will only be
1535      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1536      */
1537     @Test
testGetInfo_noMetaData_InApplication()1538     public void testGetInfo_noMetaData_InApplication() throws Exception {
1539         final ApplicationInfo ai = mPackageManager.getApplicationInfo(PACKAGE_NAME,
1540                 PackageManager.ApplicationInfoFlags.of(0));
1541         assertThat(ai.metaData).isNull();
1542     }
1543 
1544     /**
1545      * Test that {@link ComponentInfo#metaData} data associated with this activity will only be
1546      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1547      */
1548     @Test
testGetInfo_noMetaData_InActivity()1549     public void testGetInfo_noMetaData_InActivity() throws Exception {
1550         final ComponentName componentName = new ComponentName(mContext, MockActivity.class);
1551         final ActivityInfo info = mPackageManager.getActivityInfo(componentName,
1552                 PackageManager.ComponentInfoFlags.of(0));
1553         assertThat(info.metaData).isNull();
1554     }
1555 
1556     /**
1557      * Test that {@link ComponentInfo#metaData} data associated with this service will only be
1558      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1559      */
1560     @Test
testGetInfo_noMetaData_InService()1561     public void testGetInfo_noMetaData_InService() throws Exception {
1562         final ComponentName componentName = new ComponentName(mContext, MockService.class);
1563         final ServiceInfo info = mPackageManager.getServiceInfo(componentName,
1564                 PackageManager.ComponentInfoFlags.of(0));
1565         assertThat(info.metaData).isNull();
1566     }
1567 
1568     /**
1569      * Test that {@link ComponentInfo#metaData} data associated with this receiver will only be
1570      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1571      */
1572     @Test
testGetInfo_noMetaData_InBroadcastReceiver()1573     public void testGetInfo_noMetaData_InBroadcastReceiver() throws Exception {
1574         final ComponentName componentName = new ComponentName(mContext, MockReceiver.class);
1575         final ActivityInfo info = mPackageManager.getReceiverInfo(componentName,
1576                 PackageManager.ComponentInfoFlags.of(0));
1577         assertThat(info.metaData).isNull();
1578     }
1579 
1580     /**
1581      * Test that {@link ComponentInfo#metaData} data associated with this provider will only be
1582      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1583      */
1584     @Test
testGetInfo_noMetaData_InContentProvider()1585     public void testGetInfo_noMetaData_InContentProvider() throws Exception {
1586         final ComponentName componentName = new ComponentName(mContext, MockContentProvider.class);
1587         final ProviderInfo info = mPackageManager.getProviderInfo(componentName,
1588                 PackageManager.ComponentInfoFlags.of(0));
1589         assertThat(info.metaData).isNull();
1590     }
1591 
1592     /**
1593      * Test that {@link ComponentInfo#metaData} data associated with all components in this
1594      * package will not be filled in if the {@link PackageManager#GET_META_DATA} flag is not set.
1595      */
1596     @Test
testGetInfo_checkMetaData_InPackage()1597     public void testGetInfo_checkMetaData_InPackage() throws Exception {
1598         final PackageInfo info = mPackageManager.getPackageInfo(PACKAGE_NAME,
1599                 PackageManager.PackageInfoFlags.of(
1600                         GET_META_DATA | GET_ACTIVITIES | GET_SERVICES | GET_RECEIVERS
1601                                 | GET_PROVIDERS));
1602 
1603         checkMetaData(new PackageItemInfo(info.applicationInfo));
1604         checkMetaData(new PackageItemInfo(
1605                 findPackageItemOrFail(info.activities, "android.content.cts.MockActivity")));
1606         checkMetaData(new PackageItemInfo(
1607                 findPackageItemOrFail(info.services, "android.content.cts.MockService")));
1608         checkMetaData(new PackageItemInfo(
1609                 findPackageItemOrFail(info.receivers, "android.content.cts.MockReceiver")));
1610         checkMetaData(new PackageItemInfo(
1611                 findPackageItemOrFail(info.providers, "android.content.cts.MockContentProvider")));
1612     }
1613 
1614     /**
1615      * Test that {@link ComponentInfo#metaData} data associated with this application will only be
1616      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1617      */
1618     @Test
testGetInfo_checkMetaData_InApplication()1619     public void testGetInfo_checkMetaData_InApplication() throws Exception {
1620         final ApplicationInfo ai = mPackageManager.getApplicationInfo(PACKAGE_NAME,
1621                 PackageManager.ApplicationInfoFlags.of(GET_META_DATA));
1622         checkMetaData(new PackageItemInfo(ai));
1623     }
1624 
1625     /**
1626      * Test that {@link ComponentInfo#metaData} data associated with this activity will only be
1627      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1628      */
1629     @Test
testGetInfo_checkMetaData_InActivity()1630     public void testGetInfo_checkMetaData_InActivity() throws Exception {
1631         final ComponentName componentName = new ComponentName(mContext, MockActivity.class);
1632         final ActivityInfo ai = mPackageManager.getActivityInfo(componentName,
1633                 PackageManager.ComponentInfoFlags.of(GET_META_DATA));
1634         checkMetaData(new PackageItemInfo(ai));
1635     }
1636 
1637     /**
1638      * Test that {@link ComponentInfo#metaData} data associated with this service will only be
1639      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1640      */
1641     @Test
testGetInfo_checkMetaData_InService()1642     public void testGetInfo_checkMetaData_InService() throws Exception {
1643         final ComponentName componentName = new ComponentName(mContext, MockService.class);
1644         final ServiceInfo info = mPackageManager.getServiceInfo(componentName,
1645                 PackageManager.ComponentInfoFlags.of(GET_META_DATA));
1646         checkMetaData(new PackageItemInfo(info));
1647     }
1648 
1649     /**
1650      * Test that {@link ComponentInfo#metaData} data associated with this receiver will only be
1651      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1652      */
1653     @Test
testGetInfo_checkMetaData_InBroadcastReceiver()1654     public void testGetInfo_checkMetaData_InBroadcastReceiver() throws Exception {
1655         final ComponentName componentName = new ComponentName(mContext, MockReceiver.class);
1656         final ActivityInfo info = mPackageManager.getReceiverInfo(componentName,
1657                 PackageManager.ComponentInfoFlags.of(GET_META_DATA));
1658         checkMetaData(new PackageItemInfo(info));
1659     }
1660 
1661     /**
1662      * Test that {@link ComponentInfo#metaData} data associated with this provider will only be
1663      * filled in if the {@link PackageManager#GET_META_DATA} flag is set.
1664      */
1665     @Test
testGetInfo_checkMetaData_InContentProvider()1666     public void testGetInfo_checkMetaData_InContentProvider() throws Exception {
1667         final ComponentName componentName = new ComponentName(mContext, MockContentProvider.class);
1668         final ProviderInfo info = mPackageManager.getProviderInfo(componentName,
1669                 PackageManager.ComponentInfoFlags.of(GET_META_DATA));
1670         checkMetaData(new PackageItemInfo(info));
1671     }
1672 
checkMetaData(@onNull PackageItemInfo ci)1673     private void checkMetaData(@NonNull PackageItemInfo ci)
1674             throws IOException, XmlPullParserException, NameNotFoundException {
1675         final Bundle metaData = ci.metaData;
1676         final Resources res = mPackageManager.getResourcesForApplication(ci.packageName);
1677         assertWithMessage("No meta-data found").that(metaData).isNotNull();
1678 
1679         assertThat(metaData.getString("android.content.cts.string")).isEqualTo("foo");
1680         assertThat(metaData.getBoolean("android.content.cts.boolean")).isTrue();
1681         assertThat(metaData.getInt("android.content.cts.integer")).isEqualTo(100);
1682         assertThat(metaData.getInt("android.content.cts.color")).isEqualTo(0xff000000);
1683         assertThat(metaData.getFloat("android.content.cts.float")).isEqualTo(100.1f);
1684         assertThat(metaData.getInt("android.content.cts.reference")).isEqualTo(R.xml.metadata);
1685 
1686         XmlResourceParser xml = null;
1687         TypedArray a = null;
1688         try {
1689             xml = ci.loadXmlMetaData(mPackageManager, "android.content.cts.reference");
1690             assertThat(xml).isNotNull();
1691 
1692             int type;
1693             while ((type = xml.next()) != XmlPullParser.START_TAG
1694                     && type != XmlPullParser.END_DOCUMENT) {
1695                 // Seek parser to start tag.
1696             }
1697             assertThat(type).isEqualTo(XmlPullParser.START_TAG);
1698             assertThat(xml.getName()).isEqualTo("thedata");
1699 
1700             assertThat(xml.getAttributeValue(null, "rawText")).isEqualTo("some raw text");
1701             assertThat(xml.getAttributeIntValue(null, "rawColor", 0)).isEqualTo(0xffffff00);
1702             assertThat(xml.getAttributeValue(null, "rawColor")).isEqualTo("#ffffff00");
1703 
1704             a = res.obtainAttributes(xml, new int[]{android.R.attr.text, android.R.attr.color});
1705             assertThat(a.getString(0)).isEqualTo("metadata text");
1706             assertThat(a.getColor(1, 0)).isEqualTo(0xffff0000);
1707             assertThat(a.getString(1)).isEqualTo("#ffff0000");
1708         } finally {
1709             if (a != null) {
1710                 a.recycle();
1711             }
1712             if (xml != null) {
1713                 xml.close();
1714             }
1715         }
1716     }
1717 
1718     @Test
testGetApplicationInfo_ApexSupported_MatchesApex()1719     public void testGetApplicationInfo_ApexSupported_MatchesApex() throws Exception {
1720         ApplicationInfo ai = mPackageManager.getApplicationInfo(
1721                 SHIM_APEX_PACKAGE_NAME,
1722                 PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_APEX));
1723         assertThat(ai.sourceDir).isEqualTo("/system/apex/com.android.apex.cts.shim.apex");
1724         assertThat(ai.publicSourceDir).isEqualTo(ai.sourceDir);
1725         assertThat(ai.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(ApplicationInfo.FLAG_SYSTEM);
1726         assertThat(ai.flags & ApplicationInfo.FLAG_INSTALLED)
1727                 .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
1728     }
1729 
1730     @Test
testGetApplicationInfo_icon_MatchesUseRoundIcon()1731     public void testGetApplicationInfo_icon_MatchesUseRoundIcon() throws Exception {
1732         installPackage(HELLO_WORLD_APK);
1733         final boolean useRoundIcon = mContext.getResources().getBoolean(
1734                 mContext.getResources().getIdentifier("config_useRoundIcon", "bool", "android"));
1735         final ApplicationInfo info = mPackageManager.getApplicationInfo(HELLO_WORLD_PACKAGE_NAME,
1736                 PackageManager.ApplicationInfoFlags.of(0));
1737         assertThat(info.icon).isEqualTo((useRoundIcon ? info.roundIconRes : info.iconRes));
1738     }
1739 
assertShimApexInfoIsCorrect(PackageInfo packageInfo)1740     private static void assertShimApexInfoIsCorrect(PackageInfo packageInfo) {
1741         assertThat(packageInfo.packageName).isEqualTo(SHIM_APEX_PACKAGE_NAME);
1742         assertThat(packageInfo.getLongVersionCode()).isEqualTo(1);
1743         assertThat(packageInfo.isApex).isTrue();
1744         assertThat(packageInfo.applicationInfo.sourceDir).isEqualTo(
1745                 "/system/apex/com.android.apex.cts.shim.apex");
1746         assertThat(packageInfo.applicationInfo.publicSourceDir)
1747                 .isEqualTo(packageInfo.applicationInfo.sourceDir);
1748         // Verify that legacy mechanism for handling signatures is supported.
1749         Signature[] pastSigningCertificates =
1750                 packageInfo.signingInfo.getSigningCertificateHistory();
1751         assertThat(packageInfo.signatures)
1752                 .asList().containsExactly((Object[]) pastSigningCertificates);
1753     }
1754 
1755     /**
1756      * Runs a test for all combinations of a set of flags
1757      *
1758      * @param flagValues Which flags to use
1759      * @param test       The test
1760      */
runTestWithFlags(int[] flagValues, Consumer<Integer> test)1761     public void runTestWithFlags(int[] flagValues, Consumer<Integer> test) {
1762         for (int i = 0; i < (1 << flagValues.length); i++) {
1763             int flags = 0;
1764             for (int j = 0; j < flagValues.length; j++) {
1765                 if ((i & (1 << j)) != 0) {
1766                     flags |= flagValues[j];
1767                 }
1768             }
1769             try {
1770                 test.accept(flags);
1771             } catch (Throwable t) {
1772                 throw new AssertionError(
1773                         "Test failed for flags 0x" + String.format("%08x", flags), t);
1774             }
1775         }
1776     }
1777 
1778     /**
1779      * Test that the MATCH_FACTORY_ONLY flag doesn't add new package names in the result of
1780      * getInstalledPackages.
1781      */
1782     @Test
testGetInstalledPackages_WithFactoryFlag_IsSubset()1783     public void testGetInstalledPackages_WithFactoryFlag_IsSubset() {
1784         runTestWithFlags(PACKAGE_INFO_MATCH_FLAGS,
1785                 this::testGetInstalledPackages_WithFactoryFlag_IsSubset);
1786     }
1787 
testGetInstalledPackages_WithFactoryFlag_IsSubset(int flags)1788     public void testGetInstalledPackages_WithFactoryFlag_IsSubset(int flags) {
1789         List<PackageInfo> packageInfos = mPackageManager.getInstalledPackages(
1790                 PackageManager.PackageInfoFlags.of(flags));
1791         List<PackageInfo> packageInfos2 = mPackageManager.getInstalledPackages(
1792                 PackageManager.PackageInfoFlags.of(flags | MATCH_FACTORY_ONLY));
1793         Set<String> supersetNames =
1794                 packageInfos.stream().map(pi -> pi.packageName).collect(Collectors.toSet());
1795 
1796         for (PackageInfo pi : packageInfos2) {
1797             if (!supersetNames.contains(pi.packageName)) {
1798                 throw new AssertionError(
1799                         "The subset contains packages that the superset doesn't contain.");
1800             }
1801         }
1802     }
1803 
1804     /**
1805      * Test that the MATCH_FACTORY_ONLY flag filters out all non-system packages in the result of
1806      * getInstalledPackages.
1807      */
1808     @Test
testGetInstalledPackages_WithFactoryFlag_ImpliesSystem()1809     public void testGetInstalledPackages_WithFactoryFlag_ImpliesSystem() {
1810         runTestWithFlags(PACKAGE_INFO_MATCH_FLAGS,
1811                 this::testGetInstalledPackages_WithFactoryFlag_ImpliesSystem);
1812     }
1813 
testGetInstalledPackages_WithFactoryFlag_ImpliesSystem(int flags)1814     public void testGetInstalledPackages_WithFactoryFlag_ImpliesSystem(int flags) {
1815         List<PackageInfo> packageInfos =
1816                 mPackageManager.getInstalledPackages(
1817                         PackageManager.PackageInfoFlags.of(flags | MATCH_FACTORY_ONLY));
1818         for (PackageInfo pi : packageInfos) {
1819             if (!pi.applicationInfo.isSystemApp()) {
1820                 throw new AssertionError(pi.packageName + " is not a system app.");
1821             }
1822         }
1823     }
1824 
1825     /**
1826      * Test that we con't have conflicting package names between APK and APEX.
1827      */
1828     @Test
testGetInstalledPackages_WithApexFlag_ContainsNoDuplicates()1829     public void testGetInstalledPackages_WithApexFlag_ContainsNoDuplicates() {
1830         List<PackageInfo> packageInfos = mPackageManager.getInstalledPackages(
1831                 PackageManager.PackageInfoFlags.of(MATCH_APEX));
1832         final Set<String> apexPackageNames = packageInfos.stream()
1833                 .filter(pi -> pi.isApex).map(pi -> pi.packageName).collect(Collectors.toSet());
1834         final Set<String> apkPackageNames = packageInfos.stream()
1835                 .filter(pi -> !pi.isApex).map(pi -> pi.packageName).collect(Collectors.toSet());
1836         for (String packageName : apkPackageNames) {
1837             if (apexPackageNames.contains(packageName)) {
1838                 expect.withMessage("Conflicting APK package " + packageName + " detected").fail();
1839             }
1840         }
1841     }
1842 
1843     /**
1844      * Test that the MATCH_FACTORY_ONLY flag doesn't add the same package multiple times since there
1845      * may be multiple versions of a system package on the device.
1846      */
1847     @Test
testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates()1848     public void testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates() {
1849         final Set<String> packageNames = new HashSet<>();
1850         runTestWithFlags(PACKAGE_INFO_MATCH_FLAGS,
1851                 flags -> testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates(flags,
1852                         packageNames));
1853     }
1854 
testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates(int flags, Set<String> packageNames)1855     public void testGetInstalledPackages_WithFactoryFlag_ContainsNoDuplicates(int flags,
1856             Set<String> packageNames) {
1857         List<PackageInfo> packageInfos =
1858                 mPackageManager.getInstalledPackages(
1859                         PackageManager.PackageInfoFlags.of(flags | MATCH_FACTORY_ONLY));
1860 
1861         final Set<String> localPackageNames = new HashSet<>();
1862         for (PackageInfo pi : packageInfos) {
1863             final String packageName = pi.packageName;
1864             // Duplicate: already in local.
1865             // Dedup error messages: not in global.
1866             if (!localPackageNames.add(pi.packageName) && packageNames.add(packageName)) {
1867                 expect.withMessage("Duplicate package " + packageName + " detected").fail();
1868             }
1869         }
1870     }
1871 
1872     @Test
testInstallTestOnlyPackagePermission_onlyGrantedToShell()1873     public void testInstallTestOnlyPackagePermission_onlyGrantedToShell() {
1874         List<PackageInfo> packages = mPackageManager.getPackagesHoldingPermissions(
1875                 new String[]{INSTALL_TEST_ONLY_PACKAGE}, PackageManager.PackageInfoFlags.of(0));
1876 
1877         assertThat(packages).hasSize(1);
1878         assertThat(packages.get(0).packageName).isEqualTo(SHELL_PACKAGE_NAME);
1879     }
1880 
1881     @Test
testInstall_withLongPackageName_fail()1882     public void testInstall_withLongPackageName_fail() {
1883         assertThat(installPackage(LONG_PACKAGE_NAME_APK)).isFalse();
1884     }
1885 
1886     @Test
testInstall_withLongSharedUserId_fail()1887     public void testInstall_withLongSharedUserId_fail() {
1888         assertThat(installPackage(LONG_SHARED_USER_ID_APK)).isFalse();
1889     }
1890 
1891     @Test
testInstall_withMaxPackageName_success()1892     public void testInstall_withMaxPackageName_success() {
1893         assertThat(installPackage(MAX_PACKAGE_NAME_APK)).isTrue();
1894     }
1895 
1896     @Test
testInstall_withMaxSharedUserId_success()1897     public void testInstall_withMaxSharedUserId_success() {
1898         assertThat(installPackage(MAX_SHARED_USER_ID_APK)).isTrue();
1899     }
1900 
1901     @Test
testInstall_withLongUsesPermissionName_fail()1902     public void testInstall_withLongUsesPermissionName_fail() {
1903         String expectedErrorCode = "INSTALL_PARSE_FAILED";
1904         String installResult = installPackageWithResult(LONG_USES_PERMISSION_NAME_APK);
1905         assertThat(installResult).contains(expectedErrorCode);
1906     }
1907 
1908     @Test
testUpdateShellFailed()1909     public void testUpdateShellFailed() throws Exception {
1910         // First make sure that shell is not updatable, otherwise the test would eventually fail
1911         // and put the system in bad state.
1912         String isShellUpdatable = parsePackageDump(SHELL_PACKAGE_NAME, "    updatableSystem=");
1913         assertThat(isShellUpdatable).contains("false");
1914 
1915         var result = SystemUtil.runShellCommand("pm install -t -g " + SHELL_NAME_APK);
1916         boolean installationNotAllowed = result.contains(
1917                 "Installation of this package is not allowed");
1918         // This test works correctly if platform and cts are built using the same certificate.
1919         // Otherwise the install will still fail, but for a different reason.
1920         boolean signatureMismatch = result.contains(
1921                 "signatures do not match newer version");
1922         assertTrue(installationNotAllowed || signatureMismatch);
1923     }
1924 
1925     @Test
testInstallNonUpdatableSystemFailed()1926     public void testInstallNonUpdatableSystemFailed() {
1927         installPackage(HELLO_WORLD_APK);
1928         assertThat(SystemUtil.runShellCommand(
1929                 "pm install -t -g " + HELLO_WORLD_NON_UPDATABLE_SYSTEM_APK)).contains(
1930                 "Non updatable system package");
1931     }
1932 
1933     @Test
testSharedUidMaxSdkVersion()1934     public void testSharedUidMaxSdkVersion() throws Exception {
1935         assertThat(installPackageWithResult(HELLO_WORLD_SHARED_UID_APK)).isEqualTo("Success\n");
1936         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
1937         String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
1938                 "    privatePkgFlags=[");
1939         assertThat(privatePkgFlags).doesNotContain("PRIVILEGED");
1940     }
1941 
1942     @Test
1943     @RequiresFlagsEnabled(FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS)
testInstallAppSharedSystemUidAllowlisted()1944     public void testInstallAppSharedSystemUidAllowlisted() {
1945         var result = SystemUtil.runShellCommand("pm install -t -g " + HELLO_WORLD_SETTINGS);
1946         if (result.contains("no signatures that match those in shared user android.uid.system")) {
1947             // This is a <unit> test, not a proper CTS.
1948             // While certificate for HelloWorldSettings is "platform", it might not be THE platform.
1949             // This test works correctly if platform and cts are built using the same certificate.
1950             // Otherwise the install will still fail, but for a different reason.
1951             return;
1952         }
1953         assertThat(result).isEqualTo("Success\n");
1954         uninstallPackage(HELLO_WORLD_SETTINGS_PACKAGE_NAME);
1955     }
1956 
1957     @Test
1958     @RequiresFlagsEnabled(FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS)
testInstallAppSharedSystemUid()1959     public void testInstallAppSharedSystemUid() {
1960         var result = SystemUtil.runShellCommand("pm install -t -g " + HELLO_WORLD_SETTINGS2);
1961         if (result.contains("no signatures that match those in shared user android.uid.system")) {
1962             // This is a <unit> test, not a proper CTS.
1963             // While certificate for HelloWorldSettings is "platform", it might not be THE platform.
1964             // This test works correctly if platform and cts are built using the same certificate.
1965             // Otherwise the install will still fail, but for a different reason.
1966             return;
1967         }
1968         if (!Build.IS_DEBUGGABLE) {
1969             assertThat(result).contains("Non-preload app " + HELLO_WORLD_SETTINGS2_PACKAGE_NAME
1970                     + " signed with platform signature and joining shared uid");
1971         } else {
1972             assertThat(result).isEqualTo("Success\n");
1973             uninstallPackage(HELLO_WORLD_SETTINGS2_PACKAGE_NAME);
1974         }
1975     }
1976 
1977     @Test
testUpdateSystemApp()1978     public void testUpdateSystemApp() throws Exception {
1979         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(SETTINGS_PROVIDER_PACKAGE_NAME,
1980                 PackageManager.ApplicationInfoFlags.of(0));
1981         assertNotNull(appInfo.getBaseCodePath());
1982         assertThat(installPackageWithResult(appInfo.getBaseCodePath())).isEqualTo("Success\n");
1983     }
1984 
1985     @Test
testInstall_invalidInstallerName_installerNameRejected()1986     public void testInstall_invalidInstallerName_installerNameRejected() {
1987         installPackageWithInstallerPkgName(HELLO_WORLD_APK, INVALID_PACKAGE_NAME);
1988         String dumpsys = SystemUtil.runShellCommand("dumpsys package " + HELLO_WORLD_PACKAGE_NAME);
1989 
1990         String initiatingPackageName = parseDumpsysAndGet(dumpsys, "initiatingPackageName");
1991         assertEquals(SHELL_PACKAGE_NAME, initiatingPackageName);
1992 
1993         String installerPackageName = parseDumpsysAndGet(dumpsys, "installerPackageName");
1994         assertNull(installerPackageName);
1995     }
1996 
1997     @Test
testInstall_nonExistentInstallerName_installerNameNull()1998     public void testInstall_nonExistentInstallerName_installerNameNull() {
1999         installPackageWithInstallerPkgName(HELLO_WORLD_APK, NON_EXISTENT_PACKAGE_NAME);
2000         String dumpsys = SystemUtil.runShellCommand("dumpsys package " + HELLO_WORLD_PACKAGE_NAME);
2001 
2002         String initiatingPackageName = parseDumpsysAndGet(dumpsys, "initiatingPackageName");
2003         assertEquals(SHELL_PACKAGE_NAME, initiatingPackageName);
2004 
2005         String installerPackageName = parseDumpsysAndGet(dumpsys, "installerPackageName");
2006         assertNull(installerPackageName);
2007     }
2008 
installPackageWithResult(String apkPath)2009     private String installPackageWithResult(String apkPath) {
2010         return SystemUtil.runShellCommand("pm install -t " + apkPath);
2011     }
2012 
installPackage(String apkPath)2013     private boolean installPackage(String apkPath) {
2014         return SystemUtil.runShellCommand(
2015                 "pm install -t " + apkPath).equals("Success\n");
2016     }
2017 
installPackage(String apkPath, String expectedResultStartsWith)2018     private void installPackage(String apkPath, String expectedResultStartsWith)
2019             throws IOException {
2020         String result = SystemUtil.runShellCommand("pm install -t -g " + apkPath);
2021         assertTrue(result, result.startsWith(expectedResultStartsWith));
2022     }
2023 
addSplitDontKill(String packageName, String splitPath)2024     private boolean addSplitDontKill(String packageName, String splitPath) {
2025         return SystemUtil.runShellCommand(
2026                 "pm install-streaming -p " + packageName + " --dont-kill -t " + splitPath).equals(
2027                 "Success\n");
2028     }
2029 
installPackageWithInstallerPkgName(String apkPath, String installerName)2030     private void installPackageWithInstallerPkgName(String apkPath, String installerName) {
2031         File file = new File(apkPath);
2032         assertEquals("Success\n", SystemUtil.runShellCommand(
2033                 "pm install -i " + installerName + " -t -g " + file.getPath()));
2034     }
2035 
parseDumpsysAndGet(String dumpsys, String key)2036     private String parseDumpsysAndGet(String dumpsys, String key) {
2037         if (dumpsys == null) {
2038             Log.e(TAG, "Dumpsys is null");
2039             return null;
2040         }
2041 
2042         Pattern pattern = Pattern.compile(key + "=(.*)");
2043         Matcher matcher = pattern.matcher(dumpsys);
2044         if (matcher.find()) {
2045             String match = matcher.group(1);
2046             return match.equals("null") ? null : match;
2047         }
2048         Log.e(TAG, "No match found for " + key);
2049         return null;
2050     }
2051 
uninstallPackage(String packageName)2052     private void uninstallPackage(String packageName) {
2053         SystemUtil.runShellCommand("pm uninstall " + packageName);
2054     }
2055 
uninstallPackageForUser(String packageName, int userId)2056     private void uninstallPackageForUser(String packageName, int userId) {
2057         SystemUtil.runShellCommand("pm uninstall --user " + userId + " " + packageName);
2058 
2059     }
2060 
installExistingPackageForUser(String packageName, int userId)2061     private void installExistingPackageForUser(String packageName, int userId) {
2062         SystemUtil.runShellCommand("pm install-existing --user " + userId + " " + packageName);
2063     }
2064 
uninstallPackageKeepData(String packageName)2065     private void uninstallPackageKeepData(String packageName) {
2066         SystemUtil.runShellCommand("pm uninstall -k " + packageName);
2067     }
2068 
uninstallPackageKeepDataForUser(String packageName, int userId)2069     private void uninstallPackageKeepDataForUser(String packageName, int userId) {
2070         SystemUtil.runShellCommand("pm uninstall -k --user " + userId + " " + packageName);
2071     }
2072 
isAppInstalled(String packageName)2073     private static boolean isAppInstalled(String packageName) {
2074         return isPackagePresent(packageName, /*matchAllPackages=*/false);
2075     }
2076 
isPackagePresent(String packageName)2077     private static boolean isPackagePresent(String packageName) {
2078         return isPackagePresent(packageName, /*matchAllPackages=*/true);
2079     }
2080 
isPackagePresent(String packageName, boolean matchAllPackages)2081     private static boolean isPackagePresent(String packageName, boolean matchAllPackages) {
2082         final String commandResult =
2083                 SystemUtil.runShellCommand("pm list packages" + (matchAllPackages ? " -a" : ""));
2084         final int prefixLength = "package:".length();
2085         return Arrays.stream(commandResult.split("\\r?\\n")).anyMatch(
2086                 line -> line.length() > prefixLength && line.substring(prefixLength).equals(
2087                         packageName));
2088     }
2089 
executeShellCommand(String command, byte[] input)2090     static String executeShellCommand(String command, byte[] input) throws IOException {
2091         var instrumentation = InstrumentationRegistry.getInstrumentation();
2092         final ParcelFileDescriptor[] pfds =
2093                 instrumentation.getUiAutomation().executeShellCommandRw(
2094                         command);
2095         ParcelFileDescriptor stdout = pfds[0];
2096         ParcelFileDescriptor stdin = pfds[1];
2097         try (FileOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(
2098                 stdin)) {
2099             outputStream.write(input);
2100         }
2101         try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(stdout)) {
2102             return new String(FileUtils.readInputStreamFully(inputStream));
2103         }
2104     }
2105 
2106 
installArchived(ArchivedPackageInfo archivedPackageInfo)2107     private void installArchived(ArchivedPackageInfo archivedPackageInfo)
2108             throws Exception {
2109         installArchived(archivedPackageInfo,
2110                 STATUS_SUCCESS, /* expectedResultStartsWith= */ null);
2111     }
2112 
installArchived(ArchivedPackageInfo archivedPackageInfo, int expectedStatus, String expectedResultStartsWith)2113     private void installArchived(ArchivedPackageInfo archivedPackageInfo, int expectedStatus,
2114                                 String expectedResultStartsWith) throws Exception {
2115         installArchivedAsUser(
2116                 archivedPackageInfo, expectedStatus, expectedResultStartsWith, mContext.getUser());
2117     }
2118 
installArchivedAsUser(ArchivedPackageInfo archivedPackageInfo, int expectedStatus, String expectedResultStartsWith, UserHandle user)2119     static void installArchivedAsUser(ArchivedPackageInfo archivedPackageInfo, int expectedStatus,
2120                                 String expectedResultStartsWith, UserHandle user) throws Exception {
2121         var instrumentation = InstrumentationRegistry.getInstrumentation();
2122         var userContext = instrumentation.getContext().createContextAsUser(user, 0);
2123         var packageInstaller = userContext.getPackageManager().getPackageInstaller();
2124         final CompletableFuture<Integer> status = new CompletableFuture<>();
2125         final CompletableFuture<String> statusMessage = new CompletableFuture<>();
2126         SystemUtil.runWithShellPermissionIdentity(instrumentation.getUiAutomation(), () -> {
2127             var params = new SessionParams(MODE_FULL_INSTALL);
2128             packageInstaller.installPackageArchived(archivedPackageInfo, params,
2129                     new IntentSender((IIntentSender) new IIntentSender.Stub() {
2130                         @Override
2131                         public void send(int code, Intent intent, String resolvedType,
2132                                 IBinder whitelistToken,
2133                                 IIntentReceiver finishedReceiver,
2134                                 String requiredPermission, Bundle options)
2135                                 throws RemoteException {
2136                             status.complete(intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
2137                                     Integer.MIN_VALUE));
2138                             String msg = intent.getStringExtra(
2139                                     PackageInstaller.EXTRA_STATUS_MESSAGE);
2140                             if (TextUtils.isEmpty(msg)) {
2141                                 msg = String.valueOf(intent.getExtras().get(Intent.EXTRA_INTENT));
2142                             }
2143                             statusMessage.complete(msg);
2144                         }
2145                     }));
2146             assertEquals(statusMessage.get(), expectedStatus, (int) status.get());
2147             if (expectedResultStartsWith != null) {
2148                 assertThat(statusMessage.get()).startsWith(expectedResultStartsWith);
2149             }
2150         }, INSTALL_PACKAGES, Manifest.permission.INTERACT_ACROSS_USERS,
2151                 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
2152     }
2153 
2154     @Test
testInvalidInstallSessionParamsPackageNames()2155     public void testInvalidInstallSessionParamsPackageNames() throws Exception {
2156         var maliciousPayload = """
2157 @null
2158 
2159 victim $UID 1 /data/user/0 default:targetSdkVersion=28 none 0 0 1 @null
2160                 """;
2161 
2162         var packageInstaller = mContext.getPackageManager().getPackageInstaller();
2163         SystemUtil.runWithShellPermissionIdentity(mInstrumentation.getUiAutomation(), () -> {
2164             var params1 = new SessionParams(MODE_FULL_INSTALL);
2165             params1.setAppPackageName(maliciousPayload);
2166             params1.setInstallerPackageName(mContext.getPackageName());
2167             var session1 = packageInstaller.getSessionInfo(packageInstaller.createSession(params1));
2168             assertThat(session1.getAppPackageName()).isNull();
2169             assertThat(session1.getInstallerPackageName()).isEqualTo(mContext.getPackageName());
2170             packageInstaller.openSession(session1.sessionId).abandon();
2171 
2172             var params2 = new SessionParams(MODE_FULL_INSTALL);
2173             params2.setAppPackageName("android.com");
2174             params2.setInstallerPackageName(maliciousPayload);
2175             var session2 = packageInstaller.getSessionInfo(packageInstaller.createSession(params2));
2176             assertThat(session2.getAppPackageName()).isEqualTo("android.com");
2177             assertThat(session2.getInstallerPackageName()).isEqualTo(mContext.getPackageName());
2178             packageInstaller.openSession(session2.sessionId).abandon();
2179         });
2180     }
2181 
2182     @Test
testGetLaunchIntentSenderForPackage()2183     public void testGetLaunchIntentSenderForPackage() throws Exception {
2184         final Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
2185                 LauncherMockActivity.class.getName(), null /* result */, false /* block */);
2186         mInstrumentation.addMonitor(monitor);
2187 
2188         try {
2189             final IntentSender intentSender = mPackageManager.getLaunchIntentSenderForPackage(
2190                     PACKAGE_NAME);
2191             assertThat(intentSender.getCreatorPackage()).isEqualTo(PACKAGE_NAME);
2192             assertThat(intentSender.getCreatorUid()).isEqualTo(mContext.getApplicationInfo().uid);
2193 
2194             sendIntent(intentSender);
2195             final Activity activity = monitor.waitForActivityWithTimeout(TIMEOUT_MS);
2196             assertThat(activity).isNotNull();
2197             activity.finish();
2198         } finally {
2199             mInstrumentation.removeMonitor(monitor);
2200         }
2201     }
2202 
2203     @Test(expected = IntentSender.SendIntentException.class)
testGetLaunchIntentSenderForPackage_noMainActivity()2204     public void testGetLaunchIntentSenderForPackage_noMainActivity() throws Exception {
2205         assertThat(installPackage(EMPTY_APP_APK)).isTrue();
2206         final PackageInfo packageInfo = mPackageManager.getPackageInfo(EMPTY_APP_PACKAGE_NAME,
2207                 PackageManager.PackageInfoFlags.of(0));
2208         assertThat(packageInfo.packageName).isEqualTo(EMPTY_APP_PACKAGE_NAME);
2209         final Intent intent = new Intent(Intent.ACTION_MAIN);
2210         intent.setPackage(EMPTY_APP_PACKAGE_NAME);
2211         assertThat(mPackageManager.queryIntentActivities(intent,
2212                 PackageManager.ResolveInfoFlags.of(0))).isEmpty();
2213 
2214         final IntentSender intentSender = mPackageManager.getLaunchIntentSenderForPackage(
2215                 EMPTY_APP_PACKAGE_NAME);
2216         assertThat(intentSender.getCreatorPackage()).isEqualTo(PACKAGE_NAME);
2217         assertThat(intentSender.getCreatorUid()).isEqualTo(mContext.getApplicationInfo().uid);
2218 
2219         sendIntent(intentSender);
2220     }
2221 
2222     @Test(expected = IntentSender.SendIntentException.class)
testGetLaunchIntentSenderForPackage_packageNotExist()2223     public void testGetLaunchIntentSenderForPackage_packageNotExist() throws Exception {
2224         try {
2225             mPackageManager.getPackageInfo(EMPTY_APP_PACKAGE_NAME,
2226                     PackageManager.PackageInfoFlags.of(0));
2227             fail(EMPTY_APP_PACKAGE_NAME + " should not exist in the device");
2228         } catch (NameNotFoundException e) {
2229         }
2230         final IntentSender intentSender = mPackageManager.getLaunchIntentSenderForPackage(
2231                 EMPTY_APP_PACKAGE_NAME);
2232         assertThat(intentSender.getCreatorPackage()).isEqualTo(PACKAGE_NAME);
2233         assertThat(intentSender.getCreatorUid()).isEqualTo(mContext.getApplicationInfo().uid);
2234 
2235         sendIntent(intentSender);
2236     }
2237 
2238     @Test
testDefaultHomeActivity_doesntChange_whenInstallAnotherLauncher()2239     public void testDefaultHomeActivity_doesntChange_whenInstallAnotherLauncher() throws Exception {
2240         final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2241                 .addCategory(Intent.CATEGORY_HOME);
2242         final String currentHomeActivity =
2243                 mPackageManager.resolveActivity(homeIntent,
2244                         PackageManager.ResolveInfoFlags.of(0)).activityInfo.name;
2245 
2246         // Install another launcher app.
2247         assertThat(installPackage(MOCK_LAUNCHER_APK)).isTrue();
2248 
2249         // There is an async operation to re-set the default home activity in Role with no way
2250         // to listen for completion once a package installed, so poll until the default home
2251         // activity is set.
2252         PollingCheck.waitFor(() -> currentHomeActivity.equals(
2253                 mPackageManager.resolveActivity(homeIntent,
2254                         PackageManager.ResolveInfoFlags.of(0)).activityInfo.name));
2255         final List<String> homeApps =
2256                 mPackageManager.queryIntentActivities(homeIntent,
2257                                 PackageManager.ResolveInfoFlags.of(0)).stream()
2258                         .map(i -> i.activityInfo.packageName).collect(Collectors.toList());
2259         assertThat(homeApps.contains(MOCK_LAUNCHER_PACKAGE_NAME)).isTrue();
2260     }
2261 
2262     @Test
setComponentEnabledSetting_nonExistentPackage_withoutPermission()2263     public void setComponentEnabledSetting_nonExistentPackage_withoutPermission() {
2264         final ComponentName componentName = ComponentName.createRelative(
2265                 NON_EXISTENT_PACKAGE_NAME, "ClassName");
2266         assertThrows(SecurityException.class, () -> mPackageManager.setComponentEnabledSetting(
2267                 componentName, COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */));
2268     }
2269 
2270     @Test
setComponentEnabledSetting_nonExistentPackage_hasPermission()2271     public void setComponentEnabledSetting_nonExistentPackage_hasPermission() {
2272         final ComponentName componentName = ComponentName.createRelative(
2273                 NON_EXISTENT_PACKAGE_NAME, "ClassName");
2274         mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
2275                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
2276 
2277         try {
2278             assertThrows(IllegalArgumentException.class,
2279                     () -> mPackageManager.setComponentEnabledSetting(componentName,
2280                             COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */));
2281         } finally {
2282             mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
2283         }
2284     }
2285 
2286     @Test
loadApplicationLabel_withLongLabelName_truncated()2287     public void loadApplicationLabel_withLongLabelName_truncated() throws Exception {
2288         assertThat(installPackage(LONG_LABEL_NAME_APK)).isTrue();
2289         final ApplicationInfo info = mPackageManager.getApplicationInfo(
2290                 EMPTY_APP_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0));
2291         final CharSequence resLabel = mPackageManager.getText(
2292                 EMPTY_APP_PACKAGE_NAME, info.labelRes, info);
2293 
2294         assertThat(resLabel.length()).isGreaterThan(MAX_SAFE_LABEL_LENGTH);
2295         assertThat(info.loadLabel(mPackageManager).length()).isEqualTo(MAX_SAFE_LABEL_LENGTH);
2296     }
2297 
2298     @Test
loadComponentLabel_withLongLabelName_truncated()2299     public void loadComponentLabel_withLongLabelName_truncated() throws Exception {
2300         assertThat(installPackage(LONG_LABEL_NAME_APK)).isTrue();
2301         final ComponentName componentName = ComponentName.createRelative(
2302                 EMPTY_APP_PACKAGE_NAME, ".MockActivity");
2303         final ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
2304                 EMPTY_APP_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0));
2305         final ActivityInfo activityInfo = mPackageManager.getActivityInfo(
2306                 componentName, PackageManager.ComponentInfoFlags.of(0));
2307         final CharSequence resLabel = mPackageManager.getText(
2308                 EMPTY_APP_PACKAGE_NAME, activityInfo.labelRes, appInfo);
2309 
2310         assertThat(resLabel.length()).isGreaterThan(MAX_SAFE_LABEL_LENGTH);
2311         assertThat(activityInfo.loadLabel(mPackageManager).length())
2312                 .isEqualTo(MAX_SAFE_LABEL_LENGTH);
2313     }
2314 
2315     @Test
setComponentEnabledSettings_withDuplicatedComponent()2316     public void setComponentEnabledSettings_withDuplicatedComponent() {
2317         final List<ComponentEnabledSetting> enabledSettings = List.of(
2318                 new ComponentEnabledSetting(
2319                         ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2320                 new ComponentEnabledSetting(
2321                         ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP));
2322 
2323         assertThrows(IllegalArgumentException.class,
2324                 () -> mPackageManager.setComponentEnabledSettings(enabledSettings));
2325     }
2326 
2327     @Test
setComponentEnabledSettings_flagDontKillAppConflict()2328     public void setComponentEnabledSettings_flagDontKillAppConflict() {
2329         final List<ComponentEnabledSetting> enabledSettings = List.of(
2330                 new ComponentEnabledSetting(
2331                         ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2332                 new ComponentEnabledSetting(
2333                         SERVICE_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, 0));
2334 
2335         assertThrows(IllegalArgumentException.class,
2336                 () -> mPackageManager.setComponentEnabledSettings(enabledSettings));
2337     }
2338 
2339     @Test
setComponentEnabledSettings_disableSelfAndStubApp_withoutPermission()2340     public void setComponentEnabledSettings_disableSelfAndStubApp_withoutPermission() {
2341         final List<ComponentEnabledSetting> enabledSettings = List.of(
2342                 new ComponentEnabledSetting(
2343                         ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2344                 new ComponentEnabledSetting(
2345                         STUB_ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, 0));
2346 
2347         assertThrows(SecurityException.class,
2348                 () -> mPackageManager.setComponentEnabledSettings(enabledSettings));
2349     }
2350 
2351     @Test
setComponentEnabledSettings_disableSelf()2352     public void setComponentEnabledSettings_disableSelf() throws Exception {
2353         final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT);
2354         final int serviceState = mPackageManager.getComponentEnabledSetting(SERVICE_COMPONENT);
2355         assertThat(activityState).isAnyOf(
2356                 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED);
2357         assertThat(serviceState).isAnyOf(
2358                 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED);
2359 
2360         try {
2361             final List<ComponentEnabledSetting> enabledSettings = List.of(
2362                     new ComponentEnabledSetting(
2363                             ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2364                     new ComponentEnabledSetting(
2365                             SERVICE_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP));
2366             setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings);
2367         } finally {
2368             final List<ComponentEnabledSetting> enabledSettings = List.of(
2369                     new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP),
2370                     new ComponentEnabledSetting(SERVICE_COMPONENT, serviceState, DONT_KILL_APP));
2371             setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings);
2372         }
2373     }
2374 
2375     @Test
setComponentEnabledSettings_disableSelfAndStubApp_killStubApp()2376     public void setComponentEnabledSettings_disableSelfAndStubApp_killStubApp()
2377             throws Exception {
2378         final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT);
2379         final int stubState = mPackageManager.getComponentEnabledSetting(STUB_ACTIVITY_COMPONENT);
2380         assertThat(activityState).isAnyOf(
2381                 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED);
2382         assertThat(stubState).isAnyOf(
2383                 COMPONENT_ENABLED_STATE_DEFAULT, COMPONENT_ENABLED_STATE_ENABLED);
2384 
2385         final Intent intent = new Intent();
2386         intent.setComponent(STUB_SERVICE_COMPONENT);
2387         final AtomicBoolean killed = new AtomicBoolean();
2388         mServiceTestRule.bindService(intent, new ServiceConnection() {
2389             @Override
2390             public void onServiceConnected(ComponentName name, IBinder service) {
2391             }
2392 
2393             @Override
2394             public void onServiceDisconnected(ComponentName name) {
2395                 killed.set(true);
2396             }
2397         }, Context.BIND_AUTO_CREATE);
2398         mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
2399                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
2400 
2401         try {
2402             final List<ComponentEnabledSetting> enabledSettings = List.of(
2403                     new ComponentEnabledSetting(
2404                             ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2405                     new ComponentEnabledSetting(
2406                             STUB_ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, 0));
2407             setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings);
2408             TestUtils.waitUntil("Waiting for the process " + STUB_PACKAGE_NAME
2409                     + " to die", () -> killed.get());
2410         } finally {
2411             final List<ComponentEnabledSetting> enabledSettings = List.of(
2412                     new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP),
2413                     new ComponentEnabledSetting(STUB_ACTIVITY_COMPONENT, stubState, 0));
2414             setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings);
2415             mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
2416         }
2417     }
2418 
2419     @Test
setComponentEnabledSettings_noStateChanged_noBroadcastReceived()2420     public void setComponentEnabledSettings_noStateChanged_noBroadcastReceived() {
2421         final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT);
2422         final int serviceState = mPackageManager.getComponentEnabledSetting(SERVICE_COMPONENT);
2423         final List<ComponentEnabledSetting> enabledSettings = List.of(
2424                 new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP),
2425                 new ComponentEnabledSetting(SERVICE_COMPONENT, serviceState, DONT_KILL_APP));
2426 
2427         assertThrows(TimeoutException.class,
2428                 () -> setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings));
2429     }
2430 
2431     @Test
setComponentEnabledSetting_disableMultiplePackagesNoKill()2432     public void setComponentEnabledSetting_disableMultiplePackagesNoKill() throws Exception {
2433         final int activityState = mPackageManager.getComponentEnabledSetting(ACTIVITY_COMPONENT);
2434         final int serviceState = mPackageManager.getComponentEnabledSetting(SERVICE_COMPONENT);
2435         assertThat(installPackage(MOCK_LAUNCHER_APK)).isTrue();
2436         final List<ComponentEnabledSetting> settings = List.of(
2437                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_ACTIVITY_COMPONENT,
2438                         COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2439                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_RECEIVER_COMPONENT,
2440                         COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2441                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_SERVICE_COMPONENT,
2442                         COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2443                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_PROVIDER_COMPONENT,
2444                         COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2445                 new ComponentEnabledSetting(
2446                         ACTIVITY_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP),
2447                 new ComponentEnabledSetting(
2448                         SERVICE_COMPONENT, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP));
2449 
2450         try {
2451             mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
2452                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
2453             setComponentEnabledSettingsAndWaitForBroadcasts(settings);
2454         } finally {
2455             final List<ComponentEnabledSetting> enabledSettings = List.of(
2456                     new ComponentEnabledSetting(ACTIVITY_COMPONENT, activityState, DONT_KILL_APP),
2457                     new ComponentEnabledSetting(SERVICE_COMPONENT, serviceState, DONT_KILL_APP));
2458             setComponentEnabledSettingsAndWaitForBroadcasts(enabledSettings);
2459             mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
2460         }
2461     }
2462 
2463     @Test
2464     @RequiresFlagsEnabled(FLAG_IMPROVE_HOME_APP_BEHAVIOR)
testEnableAndResetComponentSetting_pressHomeButton_notShowResolverActivity()2465     public void testEnableAndResetComponentSetting_pressHomeButton_notShowResolverActivity()
2466             throws Exception {
2467         final ComponentName componentName = new ComponentName(PACKAGE_NAME,
2468                 "android.content.pm.cts.FakeLauncherActivity");
2469         final String resolverActivity = getResolverActivity();
2470 
2471         try {
2472             mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
2473                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
2474             setComponentEnabledSettingsAndWaitForBroadcasts(
2475                     List.of(new ComponentEnabledSetting(componentName,
2476                             COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP)));
2477 
2478             // Press home button to trigger the resolver activity dialog to select the default home.
2479             mUiDevice.pressHome();
2480 
2481             // The resolver activity shouldn't be shown.
2482             assertThrows(AssertionFailedError.class,
2483                     () -> TestUtils.waitUntil(
2484                             "Waiting for the resolver activity to be shown.",
2485                             5 /* timeoutSecond */, () -> hasResolverActivity(resolverActivity)));
2486         } finally {
2487             setComponentEnabledSettingsAndWaitForBroadcasts(
2488                     List.of(new ComponentEnabledSetting(componentName,
2489                             COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP)));
2490             mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
2491         }
2492 
2493         // Press home button to trigger the resolver activity dialog to select the default home.
2494         mUiDevice.pressHome();
2495 
2496         // The resolver activity shouldn't be shown.
2497         assertThrows(AssertionFailedError.class,
2498                 () -> TestUtils.waitUntil(
2499                         "Waiting for the resolver activity to be shown.",
2500                         5 /* timeoutSecond */, () -> hasResolverActivity(resolverActivity)));
2501     }
2502 
getResolverActivity()2503     private String getResolverActivity() {
2504         int resId = Resources.getSystem().getIdentifier(
2505                 "config_customResolverActivity", "string", "android");
2506         String customResolverActivity = mContext.getString(resId);
2507         Log.d(TAG, "getResolverActivity customResolverActivity=" + customResolverActivity);
2508         if (TextUtils.isEmpty(customResolverActivity)) {
2509             // If custom resolver activity is not in use, it will use the Android default.
2510             return "android/com.android.internal.app.ResolverActivity";
2511         }
2512         return customResolverActivity;
2513     }
2514 
hasResolverActivity(String resolverActivity)2515     private boolean hasResolverActivity(String resolverActivity) throws Exception {
2516         String commandOutput = mUiDevice.executeShellCommand("dumpsys activity activities");
2517         final String[] lines = commandOutput.split("\\n", -1);
2518 
2519         if (lines == null) {
2520             return false;
2521         }
2522 
2523         for (int i = 0; i < lines.length; i++) {
2524             final String line = lines[i];
2525             if (line.contains("Resumed:") && line.contains(resolverActivity)) {
2526                 Log.d(TAG, "hasResolverActivity find line=" + line);
2527                 return true;
2528             }
2529         }
2530         return false;
2531     }
2532 
2533     @Test
clearApplicationUserData_resetComponentEnabledSettings()2534     public void clearApplicationUserData_resetComponentEnabledSettings() throws Exception {
2535         assertThat(installPackage(MOCK_LAUNCHER_APK)).isTrue();
2536         final List<ComponentEnabledSetting> settings = List.of(
2537                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_ACTIVITY_COMPONENT,
2538                         COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */),
2539                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_RECEIVER_COMPONENT,
2540                         COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */),
2541                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_SERVICE_COMPONENT,
2542                         COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */),
2543                 new ComponentEnabledSetting(RESET_ENABLED_SETTING_PROVIDER_COMPONENT,
2544                         COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */));
2545 
2546         try {
2547             mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
2548                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
2549             // update component enabled settings
2550             setComponentEnabledSettingsAndWaitForBroadcasts(settings);
2551 
2552             clearApplicationUserData(MOCK_LAUNCHER_PACKAGE_NAME);
2553 
2554             assertThat(mPackageManager
2555                     .getComponentEnabledSetting(RESET_ENABLED_SETTING_ACTIVITY_COMPONENT))
2556                     .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT);
2557             assertThat(mPackageManager
2558                     .getComponentEnabledSetting(RESET_ENABLED_SETTING_RECEIVER_COMPONENT))
2559                     .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT);
2560             assertThat(mPackageManager
2561                     .getComponentEnabledSetting(RESET_ENABLED_SETTING_SERVICE_COMPONENT))
2562                     .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT);
2563             assertThat(mPackageManager
2564                     .getComponentEnabledSetting(RESET_ENABLED_SETTING_PROVIDER_COMPONENT))
2565                     .isEqualTo(COMPONENT_ENABLED_STATE_DEFAULT);
2566         } finally {
2567             mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
2568         }
2569     }
2570 
setComponentEnabledSettingsAndWaitForBroadcasts( List<ComponentEnabledSetting> enabledSettings)2571     private void setComponentEnabledSettingsAndWaitForBroadcasts(
2572             List<ComponentEnabledSetting> enabledSettings)
2573             throws InterruptedException, TimeoutException {
2574         final List<ComponentName> componentsToWait = enabledSettings.stream()
2575                 .map(enabledSetting -> enabledSetting.getComponentName())
2576                 .collect(Collectors.toList());
2577         final IntentFilter filter = new IntentFilter();
2578         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
2579         filter.addDataScheme("package");
2580         final CountDownLatch latch = new CountDownLatch(1 /* count */);
2581         final BroadcastReceiver br = new BroadcastReceiver() {
2582             @Override
2583             public void onReceive(Context context, Intent intent) {
2584                 final String packageName = intent.getData() != null
2585                         ? intent.getData().getSchemeSpecificPart() : null;
2586                 final String[] receivedComponents = intent.getStringArrayExtra(
2587                         Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
2588                 if (packageName == null || receivedComponents == null) {
2589                     return;
2590                 }
2591                 for (String componentString : receivedComponents) {
2592                     componentsToWait.remove(new ComponentName(packageName, componentString));
2593                 }
2594                 if (componentsToWait.isEmpty()) {
2595                     latch.countDown();
2596                 }
2597             }
2598         };
2599         mContext.registerReceiver(br, filter, RECEIVER_EXPORTED);
2600         try {
2601             mPackageManager.setComponentEnabledSettings(enabledSettings);
2602             if (!latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
2603                 throw new TimeoutException("Package changed broadcasts for " + componentsToWait
2604                         + " not received in " + TIMEOUT_MS + "ms");
2605             }
2606             for (ComponentEnabledSetting enabledSetting : enabledSettings) {
2607                 assertThat(mPackageManager.getComponentEnabledSetting(
2608                         enabledSetting.getComponentName()))
2609                         .isEqualTo(enabledSetting.getEnabledState());
2610             }
2611         } finally {
2612             mContext.unregisterReceiver(br);
2613         }
2614     }
2615 
clearApplicationUserData(String packageName)2616     private void clearApplicationUserData(String packageName) {
2617         final StringBuilder cmd = new StringBuilder("pm clear --user ");
2618         cmd.append(UserHandle.myUserId()).append(" ");
2619         cmd.append(packageName);
2620         SystemUtil.runShellCommand(cmd.toString());
2621     }
2622 
2623     @Test
testPrebuiltSharedLibraries_existOnDevice()2624     public void testPrebuiltSharedLibraries_existOnDevice() {
2625         final List<SharedLibraryInfo> infos =
2626                 mPackageManager.getSharedLibraries(PackageManager.PackageInfoFlags.of(0)).stream()
2627                         .filter(info -> info.isBuiltin() && !info.isNative())
2628                         .collect(Collectors.toList());
2629         assertThat(infos).isNotEmpty();
2630 
2631         final List<SharedLibraryInfo> fileNotExistInfos = infos.stream()
2632                 .filter(info -> !(new File(info.getPath()).exists())).collect(
2633                         Collectors.toList());
2634         assertThat(fileNotExistInfos).isEmpty();
2635     }
2636 
2637     @Test
testInstallUpdate_applicationIsKilled()2638     public void testInstallUpdate_applicationIsKilled() throws Exception {
2639         final Intent intent = new Intent();
2640         intent.setComponent(STUB_SERVICE_COMPONENT);
2641         final AtomicBoolean killed = new AtomicBoolean();
2642         mServiceTestRule.bindService(intent, new ServiceConnection() {
2643             @Override
2644             public void onServiceConnected(ComponentName name, IBinder service) {
2645             }
2646 
2647             @Override
2648             public void onServiceDisconnected(ComponentName name) {
2649                 killed.set(true);
2650             }
2651         }, Context.BIND_AUTO_CREATE);
2652 
2653         installPackage(STUB_PACKAGE_APK);
2654         // The application should be killed after updating.
2655         TestUtils.waitUntil("Waiting for the process " + STUB_PACKAGE_NAME + " to die",
2656                 10 /* timeoutSecond */, () -> killed.get());
2657     }
2658 
2659     @Test
testInstallUpdate_dontKill_applicationIsNotKilled()2660     public void testInstallUpdate_dontKill_applicationIsNotKilled() throws Exception {
2661         installPackage(STUB_PACKAGE_APK);
2662 
2663         final Intent intent = new Intent();
2664         intent.setComponent(STUB_SERVICE_COMPONENT);
2665         final AtomicBoolean killed = new AtomicBoolean();
2666         mServiceTestRule.bindService(intent, new ServiceConnection() {
2667             @Override
2668             public void onServiceConnected(ComponentName name, IBinder service) {
2669             }
2670 
2671             @Override
2672             public void onServiceDisconnected(ComponentName name) {
2673                 killed.set(true);
2674             }
2675         }, Context.BIND_AUTO_CREATE);
2676 
2677         addSplitDontKill(STUB_PACKAGE_NAME, STUB_PACKAGE_SPLIT);
2678         // The application shouldn't be killed after updating with --dont-kill.
2679         assertThrows(AssertionFailedError.class,
2680                 () -> TestUtils.waitUntil(
2681                         "Waiting for the process " + STUB_PACKAGE_NAME + " to die",
2682                         10 /* timeoutSecond */, () -> killed.get()));
2683     }
2684 
2685     @Test
testPackageInfoFlags()2686     public void testPackageInfoFlags() {
2687         final long rawFlags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
2688                 | PackageManager.GET_CONFIGURATIONS;
2689         assertEquals(rawFlags, PackageManager.PackageInfoFlags.of(rawFlags).getValue());
2690     }
2691 
2692     @Test
testApplicationInfoFlags()2693     public void testApplicationInfoFlags() {
2694         final long rawFlags = PackageManager.GET_SHARED_LIBRARY_FILES
2695                 | PackageManager.MATCH_UNINSTALLED_PACKAGES;
2696         assertEquals(rawFlags, PackageManager.ApplicationInfoFlags.of(rawFlags).getValue());
2697     }
2698 
2699     @Test
testResolveInfoFlags()2700     public void testResolveInfoFlags() {
2701         final long rawFlags = PackageManager.MATCH_DIRECT_BOOT_AWARE
2702                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
2703                 | PackageManager.MATCH_SYSTEM_ONLY;
2704         assertEquals(rawFlags, PackageManager.ResolveInfoFlags.of(rawFlags).getValue());
2705     }
2706 
2707     @Test
testComponentInfoFlags()2708     public void testComponentInfoFlags() {
2709         final long rawFlags = PackageManager.GET_META_DATA;
2710         assertEquals(rawFlags, PackageManager.ComponentInfoFlags.of(rawFlags).getValue());
2711     }
2712 
2713     @Test
testDeleteDexopt_withoutShellIdentity()2714     public void testDeleteDexopt_withoutShellIdentity() throws Exception {
2715         assertThat(runCommand("pm delete-dexopt " + PACKAGE_NAME))
2716                 .contains(SecurityException.class.getName());
2717     }
2718 
2719     @Test
testSettingAndReserveCopyVerityProtected()2720     public void testSettingAndReserveCopyVerityProtected() throws Exception {
2721         File systemDir = new File(Environment.getDataDirectory(), "system");
2722         File settings = new File(systemDir, "packages.xml");
2723         File settingsReserveCopy = new File(systemDir, "packages.xml.reservecopy");
2724 
2725         // Primary.
2726         assertTrue(settings.exists());
2727         // Reserve copy.
2728         assertTrue(settingsReserveCopy.exists());
2729         // Temporary backup.
2730         assertFalse(new File(systemDir, "packages-backup.xml").exists());
2731 
2732         assumeTrue(VerityUtils.isFsVeritySupported());
2733         assertTrue(VerityUtils.hasFsverity(settings.getAbsolutePath()));
2734         assertTrue(VerityUtils.hasFsverity(settingsReserveCopy.getAbsolutePath()));
2735     }
2736 
runCommand(String cmd)2737     private static String runCommand(String cmd) throws Exception {
2738         final var process = Runtime.getRuntime().exec(cmd);
2739         final StringBuilder output = new StringBuilder();
2740         BufferedReader reader =
2741                 new BufferedReader(new InputStreamReader(process.getInputStream()));
2742         reader.lines().forEach(line -> output.append(line));
2743         reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
2744         reader.lines().forEach(line -> output.append(line));
2745         process.waitFor();
2746         return output.toString();
2747     }
2748 
2749     @Test
testNewAppInstalledNotificationEnabled()2750     public void testNewAppInstalledNotificationEnabled() {
2751         SystemUtil.runWithShellPermissionIdentity(mInstrumentation.getUiAutomation(), () -> {
2752             Settings.Global.putString(mContext.getContentResolver(),
2753                     Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED, "1" /* true */);
2754         }, WRITE_SECURE_SETTINGS);
2755 
2756         assertEquals(true, mPackageManager.shouldShowNewAppInstalledNotification());
2757 
2758     }
2759 
2760     @Test
testCanUserUninstall_setToTrue_returnsTrue()2761     public void testCanUserUninstall_setToTrue_returnsTrue() throws RemoteException {
2762         SystemUtil.runWithShellPermissionIdentity(mInstrumentation.getUiAutomation(), () -> {
2763             IPackageManager iPm = ActivityThread.getPackageManager();
2764             iPm.setBlockUninstallForUser(PACKAGE_NAME, true, USER_CURRENT);
2765         }, DELETE_PACKAGES);
2766 
2767         assertEquals(true, mPackageManager.canUserUninstall(PACKAGE_NAME, CURRENT));
2768     }
2769 
2770     @Test
testAppWithNoAppStorageUpdateSuccess()2771     public void testAppWithNoAppStorageUpdateSuccess() throws Exception {
2772         installPackage(TEST_HW_NO_APP_STORAGE);
2773         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
2774         // Updates that don't change value of NO_APP_DATA_STORAGE property are allowed.
2775         installPackage(TEST_HW_NO_APP_STORAGE);
2776         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
2777     }
2778 
2779     @Test
testAppUpdateAddsNoAppDataStorageProperty()2780     public void testAppUpdateAddsNoAppDataStorageProperty() throws Exception {
2781         installPackage(HELLO_WORLD_APK);
2782         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
2783         installPackage(
2784                 TEST_HW_NO_APP_STORAGE,
2785                 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Update "
2786                         + "attempted to change value of "
2787                         + "android.internal.PROPERTY_NO_APP_DATA_STORAGE");
2788     }
2789 
2790     @Test
testAppUpdateRemovesNoAppDataStorageProperty()2791     public void testAppUpdateRemovesNoAppDataStorageProperty() throws Exception {
2792         installPackage(TEST_HW_NO_APP_STORAGE);
2793         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
2794         installPackage(
2795                 HELLO_WORLD_APK,
2796                 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Update "
2797                         + "attempted to change value of "
2798                         + "android.internal.PROPERTY_NO_APP_DATA_STORAGE");
2799     }
2800 
2801     @Test
testNoAppDataStoragePropertyCanChangeAfterUninstall()2802     public void testNoAppDataStoragePropertyCanChangeAfterUninstall() throws Exception {
2803         installPackage(TEST_HW_NO_APP_STORAGE);
2804         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
2805         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
2806         // After app is uninstalled new install can change the value of the property.
2807         installPackage(HELLO_WORLD_APK);
2808         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
2809     }
2810 
2811     @Test
testQuerySdkSandboxPackageName()2812     public void testQuerySdkSandboxPackageName() throws Exception {
2813         final PackageManager pm = mPackageManager;
2814         final String name = pm.getSdkSandboxPackageName();
2815         assertNotNull(name);
2816         final ApplicationInfo info = pm.getApplicationInfo(
2817                 name, PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY));
2818         assertEquals(ApplicationInfo.FLAG_SYSTEM, info.flags & ApplicationInfo.FLAG_SYSTEM);
2819         assertTrue(info.sourceDir.startsWith("/apex/com.android.adservices"));
2820     }
2821 
2822     @Test
testGetPackagesForUid_sdkSandboxUid()2823     public void testGetPackagesForUid_sdkSandboxUid() throws Exception {
2824         final PackageManager pm = mPackageManager;
2825         final String[] pkgs = pm.getPackagesForUid(Process.toSdkSandboxUid(10239));
2826         assertEquals(1, pkgs.length);
2827         assertEquals(pm.getSdkSandboxPackageName(), pkgs[0]);
2828     }
2829 
2830     @Test
testGetNameForUid_sdkSandboxUid()2831     public void testGetNameForUid_sdkSandboxUid() throws Exception {
2832         final PackageManager pm = mPackageManager;
2833         final String pkgName = pm.getNameForUid(Process.toSdkSandboxUid(11543));
2834         assertEquals(pm.getSdkSandboxPackageName(), pkgName);
2835     }
2836 
2837     @Test
testGetNamesForUids_sdkSandboxUids()2838     public void testGetNamesForUids_sdkSandboxUids() throws Exception {
2839         final PackageManager pm = mPackageManager;
2840         final int[] uids = new int[]{Process.toSdkSandboxUid(10101)};
2841         final String[] names = pm.getNamesForUids(uids);
2842         assertEquals(1, names.length);
2843         assertEquals(pm.getSdkSandboxPackageName(), names[0]);
2844     }
2845 
2846     @Test
testShellInitiatingPkgName()2847     public void testShellInitiatingPkgName() throws Exception {
2848         installPackage(HELLO_WORLD_APK);
2849         InstallSourceInfo installSourceInfo = mPackageManager
2850                 .getInstallSourceInfo(HELLO_WORLD_PACKAGE_NAME);
2851         assertEquals(SHELL_PACKAGE_NAME, installSourceInfo.getInitiatingPackageName());
2852         assertNull(installSourceInfo.getInstallingPackageName());
2853     }
2854 
2855     @Test
testShellInitiatingPkgNameSetInstallerPkgName()2856     public void testShellInitiatingPkgNameSetInstallerPkgName() throws Exception {
2857         installPackageWithInstallerPkgName(HELLO_WORLD_APK, PACKAGE_NAME);
2858         InstallSourceInfo installSourceInfo = mPackageManager
2859                 .getInstallSourceInfo(HELLO_WORLD_PACKAGE_NAME);
2860         assertEquals(SHELL_PACKAGE_NAME, installSourceInfo.getInitiatingPackageName());
2861         assertEquals(PACKAGE_NAME, installSourceInfo.getInstallingPackageName());
2862     }
2863 
2864     @Test
testUninstall()2865     public void testUninstall() throws Exception {
2866         final int userId = mContext.getUserId();
2867         installPackage(HELLO_WORLD_APK);
2868         // Test that the installed state is true in the dumpsys
2869         assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("true");
2870         // Queryable without special flags
2871         mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2872                 PackageManager.PackageInfoFlags.of(0));
2873         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
2874         assertThat(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)).isFalse();
2875         // Not queryable even MATCH_KNOWN_PACKAGES
2876         assertThrows(NameNotFoundException.class,
2877                 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2878                         PackageManager.PackageInfoFlags.of(MATCH_KNOWN_PACKAGES)));
2879         // No installed state in dumpsys
2880         assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isNull();
2881     }
2882 
2883     @Test
testUninstallWithKeepData()2884     public void testUninstallWithKeepData() throws Exception {
2885         final int userId = mContext.getUserId();
2886         installPackage(HELLO_WORLD_APK);
2887         // Test that the installed state is true in the dumpsys
2888         assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("true");
2889         PackageInfo packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2890                 PackageManager.PackageInfoFlags.of(0));
2891         final String oldDataDir = packageInfo.applicationInfo.dataDir;
2892         final long firstInstallTime = packageInfo.firstInstallTime;
2893         // Launch activity to write data to the data dir and verify the stats
2894         launchMainActivity(HELLO_WORLD_PACKAGE_NAME);
2895         StorageStatsManager storageStatsManager =
2896                 mContext.getSystemService(StorageStatsManager.class);
2897         StorageStats stats = storageStatsManager.queryStatsForPackage(
2898                 packageInfo.applicationInfo.storageUuid, HELLO_WORLD_PACKAGE_NAME,
2899                 UserHandle.of(userId));
2900         assertThat(stats.getDataBytes()).isGreaterThan(0L);
2901 
2902         uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME);
2903         assertThat(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)).isFalse();
2904 
2905         // Queryable with MATCH_UNINSTALLED_PACKAGES and MATCH_KNOWN_PACKAGES flags
2906         expectThrows(NameNotFoundException.class,
2907                 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2908                         PackageManager.PackageInfoFlags.of(0)));
2909         expectThrows(NameNotFoundException.class,
2910                 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2911                         PackageManager.PackageInfoFlags.of(MATCH_ANY_USER)));
2912         mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2913                 PackageManager.PackageInfoFlags.of(MATCH_KNOWN_PACKAGES));
2914         packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2915                 PackageManager.PackageInfoFlags.of(MATCH_UNINSTALLED_PACKAGES | GET_SIGNATURES));
2916         assertThat(packageInfo.packageName).isEqualTo(HELLO_WORLD_PACKAGE_NAME);
2917         // Test that the code path is gone but the signing info is still available
2918         assertThat(packageInfo.applicationInfo.getCodePath()).isNull();
2919         assertThat(packageInfo.signingInfo).isNotNull();
2920         assertThat(packageInfo.applicationInfo.targetSdkVersion).isGreaterThan(0);
2921         assertThat(packageInfo.signatures).isNotNull();
2922         assertThat(packageInfo.firstInstallTime).isEqualTo(firstInstallTime);
2923         // Test that the app's data directory is preserved and matches dumpsys
2924         final String newDataDir = packageInfo.applicationInfo.dataDir;
2925         assertThat(newDataDir).isNotEmpty();
2926         assertThat(newDataDir).isEqualTo(oldDataDir);
2927         final String appDirInDump = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
2928                 "      dataDir=/data/user/" + userId);
2929         assertThat("/data/user/" + userId + appDirInDump).isEqualTo(newDataDir);
2930         assertThat(packageInfo.applicationInfo.storageUuid).isNotNull();
2931         // Test that the installed state is false in the dumpsys
2932         assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("false");
2933         // Verify the stats
2934         stats = storageStatsManager.queryStatsForPackage(
2935                 packageInfo.applicationInfo.storageUuid, HELLO_WORLD_PACKAGE_NAME,
2936                 UserHandle.of(UserHandle.myUserId()));
2937         assertThat(stats.getDataBytes()).isGreaterThan(0L);
2938         // Re-install the app and verify that the data dir is the same as before
2939         installPackage(HELLO_WORLD_APK);
2940         assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isEqualTo("true");
2941         packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2942                 PackageManager.PackageInfoFlags.of(0));
2943         assertThat(packageInfo.applicationInfo.dataDir).isEqualTo(oldDataDir);
2944         // Fully clean up and test that the query fails
2945         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
2946         assertThat(getInstalledState(HELLO_WORLD_PACKAGE_NAME, userId)).isNull();
2947         expectThrows(NameNotFoundException.class,
2948                 () -> mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2949                         PackageManager.PackageInfoFlags.of(MATCH_UNINSTALLED_PACKAGES)));
2950     }
2951 
2952     @Test
testUninstallViaApiWithNoPermissionThrowSecurityException()2953     public void testUninstallViaApiWithNoPermissionThrowSecurityException() throws Exception {
2954         installPackage(HELLO_WORLD_APK);
2955         assertThrows(SecurityException.class, () -> {
2956             mPackageManager.getPackageInstaller().uninstall(HELLO_WORLD_PACKAGE_NAME,
2957                     /* statusReceiver= */ null);
2958         });
2959     }
2960 
assertDataAppExists(String packageName)2961     private void assertDataAppExists(String packageName) throws Exception {
2962         var packageInfo = mPackageManager.getPackageInfo(packageName, MATCH_KNOWN_PACKAGES);
2963         assertThat(packageInfo.applicationInfo.dataDir).isNotNull();
2964     }
2965 
2966     @Test
testUpdateDowngradeVersionForUninstallWithKeepDataApp_fail()2967     public void testUpdateDowngradeVersionForUninstallWithKeepDataApp_fail() throws Exception {
2968         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
2969 
2970         installPackage(HELLO_WORLD_V2_APK);
2971         uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME);
2972 
2973         // The test app is not installed
2974         assertThat(isAppInstalled(HELLO_WORLD_PACKAGE_NAME)).isFalse();
2975 
2976         // Install older version failed
2977         installPackage(HELLO_WORLD_V1_APK,
2978                 "Failure [INSTALL_FAILED_VERSION_DOWNGRADE: Downgrade detected on app uninstalled"
2979                 + " with DELETE_KEEP_DATA:");
2980     }
2981 
2982     @Test
2983     @RequiresFlagsEnabled(FLAG_ARCHIVING)
testUpdateDowngradeVersionFromArchived_fail()2984     public void testUpdateDowngradeVersionFromArchived_fail() throws Exception {
2985         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
2986 
2987         assertEquals("Success\n", SystemUtil.runShellCommand(
2988                 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(),
2989                         HELLO_WORLD_V2_APK)));
2990         assertThat(SystemUtil.runShellCommand(String.format(
2991                 "pm archive %s", HELLO_WORLD_PACKAGE_NAME))).isEqualTo("Success\n");
2992         // Check "installed" flag.
2993         var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
2994                 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo;
2995         assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0);
2996         // Check archive state.
2997         assertTrue(applicationInfo.isArchived);
2998 
2999         installPackage(HELLO_WORLD_V1_APK,
3000                 "Failure [INSTALL_FAILED_VERSION_DOWNGRADE: Downgrade detected on app uninstalled"
3001                         + " with DELETE_KEEP_DATA:");
3002     }
3003 
3004     @Test
testInstallArchivedFromArchived()3005     public void testInstallArchivedFromArchived() throws Exception {
3006         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3007 
3008         assertEquals("Success\n", SystemUtil.runShellCommand(
3009                 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(),
3010                         HELLO_WORLD_APK)));
3011         assertThat(SystemUtil.runShellCommand(
3012                 String.format("pm archive %s", HELLO_WORLD_PACKAGE_NAME))).isEqualTo("Success\n");
3013         // Check "installed" flag.
3014         var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
3015                 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo;
3016         assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0);
3017         // Check archive state.
3018         assertTrue(applicationInfo.isArchived);
3019         // Not pending restore.
3020         String pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3021                 "    pendingRestore=");
3022         assertThat(pendingRestore).isNull();
3023 
3024         byte[] archivedPackage = SystemUtil.runShellCommandByteOutput(
3025                 mInstrumentation.getUiAutomation(),
3026                 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME);
3027         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3028 
3029         // Install archived APK.
3030         assertEquals("Success\n", executeShellCommand(
3031                 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(),
3032                         archivedPackage.length), archivedPackage));
3033         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3034         // Check "installed" flag once again.
3035         applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
3036                 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo;
3037         assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0);
3038         // Check archive state once again.
3039         assertTrue(applicationInfo.isArchived);
3040         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3041 
3042         // Try to install archived without installer.
3043         assertThat(executeShellCommand(
3044                 String.format("pm install-archived -t -S %s", archivedPackage.length),
3045                 archivedPackage)).startsWith("Failure [INSTALL_FAILED_SESSION_INVALID: Installer");
3046     }
3047 
3048     @Test
testInstallArchivedFromArchivedWithUser()3049     public void testInstallArchivedFromArchivedWithUser() throws Exception {
3050         final int userId = mContext.getUserId();
3051         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3052 
3053         assertEquals("Success\n", SystemUtil.runShellCommand(
3054                 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(),
3055                         HELLO_WORLD_APK)));
3056         assertThat(SystemUtil.runShellCommand(
3057                 String.format("pm archive --user %s %s", userId, HELLO_WORLD_PACKAGE_NAME))
3058         ).isEqualTo("Success\n");
3059         // Check "installed" flag.
3060         var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
3061                 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo;
3062         assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0);
3063         // Check archive state.
3064         assertTrue(applicationInfo.isArchived);
3065 
3066         if (userId != UserHandle.USER_SYSTEM) {
3067             applicationInfo = mPackageManager.getPackageInfoAsUser(HELLO_WORLD_PACKAGE_NAME,
3068                     PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES),
3069                     UserHandle.USER_SYSTEM).applicationInfo;
3070             // Installed and not archived for the other user.
3071             assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED,
3072                     ApplicationInfo.FLAG_INSTALLED);
3073             assertFalse(applicationInfo.isArchived);
3074         }
3075 
3076         byte[] archivedPackage = SystemUtil.runShellCommandByteOutput(
3077                 mInstrumentation.getUiAutomation(),
3078                 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME);
3079         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3080 
3081         // Install archived APK.
3082         assertEquals("Success\n", executeShellCommand(
3083                 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(),
3084                         archivedPackage.length), archivedPackage));
3085         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3086         // Check "installed" flag once again.
3087         applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
3088                 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo;
3089         assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0);
3090         // Check archive state once again.
3091         assertTrue(applicationInfo.isArchived);
3092     }
3093 
3094 
3095     @Test
testInstallArchivedUpdate()3096     public void testInstallArchivedUpdate() throws Exception {
3097         final int userId = mContext.getUserId();
3098         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3099 
3100         assertEquals("Success\n", SystemUtil.runShellCommand(
3101                 String.format("pm install --user %d -r -t -g %s", userId,
3102                         HELLO_WORLD_APK)));
3103         byte[] archivedPackage = SystemUtil.runShellCommandByteOutput(
3104                 mInstrumentation.getUiAutomation(),
3105                 String.format("pm get-archived-package-metadata --user %d %s",
3106                         userId, HELLO_WORLD_PACKAGE_NAME));
3107 
3108         // Try to install archived on top of fully installed app.
3109         assertThat(executeShellCommand(
3110                 String.format("pm install-archived --user %d -r -i %s -t -S %s", userId,
3111                         mContext.getPackageName(), archivedPackage.length), archivedPackage))
3112                 .startsWith("Failure [INSTALL_FAILED_SESSION_INVALID: Archived");
3113 
3114         // Uninstall and retry.
3115         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3116         assertEquals("Success\n", executeShellCommand(
3117                 String.format("pm install-archived --user %d -r -i %s -t -S %s", userId,
3118                         mContext.getPackageName(), archivedPackage.length), archivedPackage));
3119         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3120         // Pending restore.
3121         String pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3122                 "    pendingRestore=");
3123         assertThat(pendingRestore).isEqualTo("true");
3124         assertDataAppExists(HELLO_WORLD_PACKAGE_NAME);
3125         // Wrong signature.
3126         assertThat(SystemUtil.runShellCommand(
3127                 String.format("pm install --user %d -t -g %s", userId,
3128                         HELLO_WORLD_DIFF_SIGNER_APK)))
3129                 .startsWith("Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE");
3130         // Update fails because we can't derive an existing APK.
3131         assertThat(SystemUtil.runShellCommand(
3132                 String.format("pm install --user %d -t -p %s -g %s", userId,
3133                         HELLO_WORLD_PACKAGE_NAME, HELLO_WORLD_UPDATED_APK))).startsWith(
3134                 "Failure [INSTALL_FAILED_INVALID_APK: Missing existing base package");
3135         // Unarchive/full install succeeds.
3136         assertEquals("Success\n", SystemUtil.runShellCommand(
3137                 String.format("pm install --user %d -t -g %s", userId, HELLO_WORLD_UPDATED_APK)));
3138         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
3139         // pendingRestore flag will only be unset if the restore is successfully performed.
3140         // On devices that don't support backup & restore, the following checks will be skipped.
3141         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP)) {
3142             // Not pending restore.
3143             pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3144                     "    pendingRestore=");
3145             assertThat(pendingRestore).isNull();
3146             // Uninstall, keep data.
3147             assertEquals("Success\n", SystemUtil.runShellCommand(
3148                     String.format("pm uninstall --user %d -k %s", userId,
3149                             HELLO_WORLD_PACKAGE_NAME)));
3150             // Not pending restore.
3151             pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3152                     "    pendingRestore=");
3153             assertThat(pendingRestore).isNull();
3154         }
3155         // Full uninstall.
3156         assertEquals("Success\n",
3157                 SystemUtil.runShellCommand("pm uninstall " + HELLO_WORLD_PACKAGE_NAME));
3158         assertFalse(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3159     }
3160 
3161     @Test
testInstallArchivedCheckFlags()3162     public void testInstallArchivedCheckFlags() throws Exception {
3163         installPackage(HELLO_WORLD_APK);
3164         byte[] archivedPackage = SystemUtil.runShellCommandByteOutput(
3165                 mInstrumentation.getUiAutomation(),
3166                 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME);
3167         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3168 
3169         // Install a default APK.
3170         assertEquals("Success\n", executeShellCommand(
3171                 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(),
3172                         archivedPackage.length), archivedPackage));
3173         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3174         String pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, "    pkgFlags=[");
3175         assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA");
3176         assertThat(pkgFlags).contains("ALLOW_BACKUP");
3177         String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3178                 "    privatePkgFlags=[");
3179         assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE");
3180         assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA");
3181         String pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3182                 "    pendingRestore=");
3183         assertThat(pendingRestore).isEqualTo("true");
3184         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3185 
3186         installPackage(HELLO_WORLD_FLAGS_APK);
3187         byte[] archivedPackageFlags = SystemUtil.runShellCommandByteOutput(
3188                 mInstrumentation.getUiAutomation(),
3189                 "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME);
3190         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3191 
3192         // Install an APK with non default flags.
3193         assertEquals("Success\n", executeShellCommand(
3194                 String.format("pm install-archived -r -i %s -t -S %s", mContext.getPackageName(),
3195                         archivedPackageFlags.length), archivedPackageFlags));
3196         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3197         pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, "    pkgFlags=[");
3198         assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA");
3199         privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3200                 "    privatePkgFlags=[");
3201         assertThat(privatePkgFlags).contains("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE");
3202         assertThat(privatePkgFlags).contains("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA");
3203         pendingRestore = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3204                 "    pendingRestore=");
3205         assertThat(pendingRestore).isEqualTo("true");
3206         assertDataAppExists(HELLO_WORLD_PACKAGE_NAME);
3207     }
3208 
3209     /**
3210      * Test that broadcasts are sent during archival install.
3211      */
3212     @Test
testInstallArchivedBroadcasts()3213     public void testInstallArchivedBroadcasts() throws Exception {
3214         int testUserId = Process.myUserHandle().getIdentifier();
3215         final PackageBroadcastReceiver addedBroadcastReceiver = new PackageBroadcastReceiver(
3216                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_ADDED
3217         );
3218         final PackageBroadcastReceiver removedBroadcastReceiver = new PackageBroadcastReceiver(
3219                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_REMOVED
3220         );
3221         final PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver(
3222                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_UID_REMOVED
3223         );
3224         final IntentFilter intentFilter = new IntentFilter();
3225         intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
3226         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
3227         intentFilter.addDataScheme("package");
3228         final IntentFilter intentFilterForUidRemoved = new IntentFilter(Intent.ACTION_UID_REMOVED);
3229         mContext.registerReceiver(addedBroadcastReceiver, intentFilter);
3230         mContext.registerReceiver(removedBroadcastReceiver, intentFilter);
3231         mContext.registerReceiver(uidRemovedBroadcastReceiver, intentFilterForUidRemoved);
3232 
3233         try {
3234             installPackage(HELLO_WORLD_APK);
3235             // Make sure this broadcast is received so it doesn't affect the test later
3236             addedBroadcastReceiver.assertBroadcastReceived();
3237             byte[] archivedPackage = SystemUtil.runShellCommandByteOutput(
3238                     mInstrumentation.getUiAutomation(),
3239                     "pm get-archived-package-metadata " + HELLO_WORLD_PACKAGE_NAME);
3240             uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3241             // Make sure this broadcast is received so it doesn't affect the test later
3242             removedBroadcastReceiver.assertBroadcastReceived();
3243             uidRemovedBroadcastReceiver.assertBroadcastReceived();
3244 
3245             addedBroadcastReceiver.reset();
3246             removedBroadcastReceiver.reset();
3247             uidRemovedBroadcastReceiver.reset();
3248 
3249             assertEquals("Success\n", executeShellCommand(
3250                     String.format("pm install-archived -r -i %s -t -S %s",
3251                             mContext.getPackageName(), archivedPackage.length), archivedPackage));
3252 
3253             addedBroadcastReceiver.assertBroadcastReceived();
3254             Intent addedIntent = addedBroadcastReceiver.getBroadcastResult();
3255             assertNotNull(addedIntent);
3256             assertTrue(addedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false));
3257             assertFalse(addedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false));
3258 
3259             removedBroadcastReceiver.assertBroadcastReceived();
3260             Intent removedIntent = removedBroadcastReceiver.getBroadcastResult();
3261             assertNotNull(removedIntent);
3262             assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false));
3263             assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false));
3264 
3265             uidRemovedBroadcastReceiver.assertBroadcastNotReceived();
3266         } finally {
3267             mContext.unregisterReceiver(addedBroadcastReceiver);
3268             mContext.unregisterReceiver(removedBroadcastReceiver);
3269             mContext.unregisterReceiver(uidRemovedBroadcastReceiver);
3270         }
3271     }
3272 
3273     // Same tests as above, but using direct PackageInstaller API calls.
3274 
3275     @Test
3276     @RequiresFlagsEnabled(FLAG_ARCHIVING)
testInstallArchivedApiFromArchived()3277     public void testInstallArchivedApiFromArchived() throws Exception {
3278         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3279 
3280         assertEquals("Success\n", SystemUtil.runShellCommand(
3281                 String.format("pm install -r -i %s -t -g %s", mContext.getPackageName(),
3282                         HELLO_WORLD_APK)));
3283         assertThat(SystemUtil.runShellCommand(
3284                 String.format("pm archive %s", HELLO_WORLD_PACKAGE_NAME))).isEqualTo("Success\n");
3285 
3286         var packageManager = mContext.getPackageManager();
3287         var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME);
3288         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3289 
3290         // Install a default APK.
3291         installArchived(archivedPackage);
3292         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3293         // Check "installed" flag.
3294         var applicationInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
3295                 PackageManager.PackageInfoFlags.of(MATCH_ARCHIVED_PACKAGES)).applicationInfo;
3296         assertEquals(applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED, 0);
3297         // Check archive state.
3298         assertTrue(applicationInfo.isArchived);
3299         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3300     }
3301 
3302     @Test
3303     @RequiresFlagsEnabled(FLAG_ARCHIVING)
testInstallArchivedApiUpdate()3304     public void testInstallArchivedApiUpdate() throws Exception {
3305         var packageManager = mContext.getPackageManager();
3306 
3307         installPackage(HELLO_WORLD_APK);
3308         var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME);
3309 
3310         // Try to install archived on top of fully installed app.
3311         installArchived(archivedPackage, STATUS_FAILURE,
3312                 "INSTALL_FAILED_SESSION_INVALID: Archived installation");
3313 
3314         // Uninstall and retry.
3315         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3316         installArchived(archivedPackage);
3317         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3318         assertDataAppExists(HELLO_WORLD_PACKAGE_NAME);
3319         // Wrong signature.
3320         assertThat(SystemUtil.runShellCommand(
3321                 "pm install -t -g " + HELLO_WORLD_DIFF_SIGNER_APK)).startsWith(
3322                 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE");
3323         // Update fails because we can't derive an existing APK.
3324         assertThat(SystemUtil.runShellCommand(
3325                 "pm install -t -p " + HELLO_WORLD_PACKAGE_NAME + " -g "
3326                         + HELLO_WORLD_UPDATED_APK)).startsWith(
3327                 "Failure [INSTALL_FAILED_INVALID_APK: Missing existing base package");
3328         // Unarchive/full install succeeds.
3329         assertEquals("Success\n", SystemUtil.runShellCommand(
3330                 "pm install -t -g " + HELLO_WORLD_UPDATED_APK));
3331         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
3332         // Uninstall, keep data.
3333         assertEquals("Success\n",
3334                 SystemUtil.runShellCommand("pm uninstall -k " + HELLO_WORLD_PACKAGE_NAME));
3335         // Full uninstall.
3336         assertEquals("Success\n",
3337                 SystemUtil.runShellCommand("pm uninstall " + HELLO_WORLD_PACKAGE_NAME));
3338         assertFalse(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3339     }
3340 
3341     @Test
3342     @RequiresFlagsEnabled(FLAG_ARCHIVING)
testInstallArchivedApiCheckFlags()3343     public void testInstallArchivedApiCheckFlags() throws Exception {
3344         var packageManager = mContext.getPackageManager();
3345 
3346         installPackage(HELLO_WORLD_APK);
3347         var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME);
3348         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3349 
3350         // Install a default APK.
3351         installArchived(archivedPackage);
3352         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3353         String pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, "    pkgFlags=[");
3354         assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA");
3355         assertThat(pkgFlags).contains("ALLOW_BACKUP");
3356         String privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3357                 "    privatePkgFlags=[");
3358         assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE");
3359         assertThat(privatePkgFlags).doesNotContain("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA");
3360         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3361 
3362         installPackage(HELLO_WORLD_FLAGS_APK);
3363         var archivedPackageFlags = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME);
3364         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3365 
3366         // Install an APK with non default flags.
3367         installArchived(archivedPackageFlags);
3368         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3369         pkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME, "    pkgFlags=[");
3370         assertThat(pkgFlags).contains("ALLOW_CLEAR_USER_DATA");
3371         privatePkgFlags = parsePackageDump(HELLO_WORLD_PACKAGE_NAME,
3372                 "    privatePkgFlags=[");
3373         assertThat(privatePkgFlags).contains("PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE");
3374         assertThat(privatePkgFlags).contains("PRIVATE_FLAG_HAS_FRAGILE_USER_DATA");
3375         assertDataAppExists(HELLO_WORLD_PACKAGE_NAME);
3376     }
3377 
3378     @Test
3379     @RequiresFlagsEnabled(FLAG_ARCHIVING)
testInstallArchivedApiBroadcasts()3380     public void testInstallArchivedApiBroadcasts() throws Exception {
3381         var packageManager = mContext.getPackageManager();
3382 
3383         installPackage(HELLO_WORLD_APK);
3384         var archivedPackage = packageManager.getArchivedPackage(HELLO_WORLD_PACKAGE_NAME);
3385         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3386 
3387         // Wait ACTION_PACKAGE_REMOVED was dispatched for uninstall HELLO_WORLD_PACKAGE_NAME
3388         SystemClock.sleep(2_000);
3389 
3390         int testUserId = Process.myUserHandle().getIdentifier();
3391         final PackageBroadcastReceiver addedBroadcastReceiver = new PackageBroadcastReceiver(
3392                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_ADDED
3393         );
3394         final PackageBroadcastReceiver removedBroadcastReceiver = new PackageBroadcastReceiver(
3395                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_REMOVED
3396         );
3397         final PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver(
3398                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_UID_REMOVED
3399         );
3400         final IntentFilter intentFilter = new IntentFilter();
3401         intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
3402         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
3403         intentFilter.addDataScheme("package");
3404         final IntentFilter intentFilterForUidRemoved = new IntentFilter(Intent.ACTION_UID_REMOVED);
3405         mContext.registerReceiver(addedBroadcastReceiver, intentFilter);
3406         mContext.registerReceiver(removedBroadcastReceiver, intentFilter);
3407         mContext.registerReceiver(uidRemovedBroadcastReceiver, intentFilterForUidRemoved);
3408 
3409         try {
3410             installArchived(archivedPackage);
3411 
3412             addedBroadcastReceiver.assertBroadcastReceived();
3413             Intent addedIntent = addedBroadcastReceiver.getBroadcastResult();
3414             assertNotNull(addedIntent);
3415             assertTrue(addedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false));
3416             assertFalse(addedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false));
3417 
3418             removedBroadcastReceiver.assertBroadcastReceived();
3419             Intent removedIntent = removedBroadcastReceiver.getBroadcastResult();
3420             assertNotNull(removedIntent);
3421             assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_ARCHIVAL, false));
3422             assertTrue(removedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false));
3423 
3424             uidRemovedBroadcastReceiver.assertBroadcastNotReceived();
3425         } finally {
3426             mContext.unregisterReceiver(addedBroadcastReceiver);
3427             mContext.unregisterReceiver(removedBroadcastReceiver);
3428             mContext.unregisterReceiver(uidRemovedBroadcastReceiver);
3429         }
3430     }
3431 
readCertificate()3432     private static Certificate readCertificate() throws Exception {
3433         try (InputStream is = new FileInputStream(DIFF_SIGNER_CERTIFICATE)) {
3434             CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
3435             return certFactory.generateCertificate(is);
3436         }
3437     }
3438 
3439     @Test
3440     @RequiresFlagsEnabled(FLAG_ARCHIVING)
testInstallArchivedApi()3441     public void testInstallArchivedApi() throws Exception {
3442         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3443 
3444         Certificate certificate = readCertificate();
3445         Signature signature = new Signature(new Certificate[] { certificate });
3446         PublicKey publicKey = certificate.getPublicKey();
3447 
3448         SigningInfo signingInfo = new SigningInfo(/* schemeVersion= */3, List.of(signature),
3449                 List.of(publicKey), null);
3450 
3451         var wrongLabel = "HelloWorldTitle1";
3452         var wrongComponent = new ComponentName(HELLO_WORLD_PACKAGE_NAME, ".MainActivity1");
3453 
3454         var archivedActivity = new ArchivedActivityInfo(wrongLabel, wrongComponent);
3455         assertEquals("HelloWorldTitle1", archivedActivity.getLabel());
3456         assertEquals(wrongComponent, archivedActivity.getComponentName());
3457 
3458         var correctLabel = "HelloWorldTitle";
3459         var correctComponent = new ComponentName(HELLO_WORLD_PACKAGE_NAME, ".MainActivity");
3460         var icon = new BitmapDrawable(/* res= */null, TEST_ICON);
3461         var monochromeIcon = new BitmapDrawable(/* res= */null, TEST_ICON_MONO);
3462 
3463         archivedActivity.setLabel(correctLabel);
3464         assertEquals(correctLabel, archivedActivity.getLabel());
3465         archivedActivity.setComponentName(correctComponent);
3466         assertEquals(correctComponent, archivedActivity.getComponentName());
3467         archivedActivity.setIcon(icon);
3468         assertEquals(icon, archivedActivity.getIcon());
3469         archivedActivity.setMonochromeIcon(monochromeIcon);
3470         assertEquals(monochromeIcon, archivedActivity.getMonochromeIcon());
3471 
3472         var activities = List.of(archivedActivity);
3473 
3474         var wrongPackageName = PACKAGE_NAME;
3475         var wrongSigningInfo = new SigningInfo();
3476         var wrongLauncherActivities = new ArrayList<ArchivedActivityInfo>();
3477 
3478         var archivedPackage = new ArchivedPackageInfo(wrongPackageName,
3479                 wrongSigningInfo, wrongLauncherActivities);
3480         assertEquals(wrongPackageName, archivedPackage.getPackageName());
3481         assertEquals(wrongSigningInfo, archivedPackage.getSigningInfo());
3482         assertEquals(wrongLauncherActivities, archivedPackage.getLauncherActivities());
3483 
3484         archivedPackage.setPackageName(HELLO_WORLD_PACKAGE_NAME);
3485         assertEquals(HELLO_WORLD_PACKAGE_NAME, archivedPackage.getPackageName());
3486         archivedPackage.setSigningInfo(signingInfo);
3487         assertEquals(signingInfo, archivedPackage.getSigningInfo());
3488         assertEquals(3, archivedPackage.getSigningInfo().getSchemeVersion());
3489         assertThat(archivedPackage.getSigningInfo().getPublicKeys()).containsExactlyElementsIn(
3490                 List.of(publicKey));
3491         archivedPackage.setLauncherActivities(activities);
3492         assertEquals(activities, archivedPackage.getLauncherActivities());
3493         archivedPackage.setVersionCode(1);
3494         assertEquals(1, archivedPackage.getVersionCode());
3495         archivedPackage.setVersionCodeMajor(0);
3496         assertEquals(0, archivedPackage.getVersionCodeMajor());
3497         archivedPackage.setTargetSdkVersion(27);
3498         assertEquals(27, archivedPackage.getTargetSdkVersion());
3499         archivedPackage.setDefaultToDeviceProtectedStorage(null);
3500         assertNull(archivedPackage.getDefaultToDeviceProtectedStorage());
3501         archivedPackage.setRequestLegacyExternalStorage("true");
3502         assertEquals("true", archivedPackage.getRequestLegacyExternalStorage());
3503         archivedPackage.setUserDataFragile("true");
3504         assertEquals("true", archivedPackage.getUserDataFragile());
3505 
3506         // Install archived.
3507         installArchived(archivedPackage);
3508         assertTrue(isPackagePresent(HELLO_WORLD_PACKAGE_NAME));
3509 
3510         // Wrong signature (we are using cts-testkey1).
3511         assertThat(SystemUtil.runShellCommand(
3512                 "pm install -t -g " + HELLO_WORLD_UPDATED_APK)).startsWith(
3513                 "Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE");
3514         // Unarchive/full install succeeds.
3515         assertEquals("Success\n", SystemUtil.runShellCommand(
3516                 "pm install -t -g " + HELLO_WORLD_DIFF_SIGNER_APK));
3517         assertTrue(isAppInstalled(HELLO_WORLD_PACKAGE_NAME));
3518 
3519         uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3520     }
3521 
3522     @Test
testPackageRemovedBroadcastsSingleUser()3523     public void testPackageRemovedBroadcastsSingleUser() throws Exception {
3524         installPackage(HELLO_WORLD_APK);
3525         final int testUserId = Process.myUserHandle().getIdentifier();
3526         final PackageBroadcastReceiver
3527                 removedBroadcastReceiver = new PackageBroadcastReceiver(
3528                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_REMOVED
3529         );
3530         final PackageBroadcastReceiver fullyRemovedBroadcastReceiver = new PackageBroadcastReceiver(
3531                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_FULLY_REMOVED
3532         );
3533         final PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver(
3534                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_UID_REMOVED
3535         );
3536         final IntentFilter intentFilter = new IntentFilter();
3537         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
3538         intentFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
3539         intentFilter.addDataScheme("package");
3540 
3541         final IntentFilter intentFilterForUidRemoved = new IntentFilter(Intent.ACTION_UID_REMOVED);
3542         mContext.registerReceiver(removedBroadcastReceiver, intentFilter);
3543         mContext.registerReceiver(fullyRemovedBroadcastReceiver, intentFilter);
3544         mContext.registerReceiver(uidRemovedBroadcastReceiver, intentFilterForUidRemoved);
3545 
3546         try {
3547             // Test uninstall -k without --user
3548             uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME);
3549             removedBroadcastReceiver.assertBroadcastReceived();
3550             fullyRemovedBroadcastReceiver.assertBroadcastNotReceived();
3551             uidRemovedBroadcastReceiver.assertBroadcastNotReceived();
3552             removedBroadcastReceiver.reset();
3553             // Test uninstall -k with --user
3554             installPackage(HELLO_WORLD_APK);
3555             uninstallPackageKeepDataForUser(HELLO_WORLD_PACKAGE_NAME, testUserId);
3556             removedBroadcastReceiver.assertBroadcastReceived();
3557             fullyRemovedBroadcastReceiver.assertBroadcastNotReceived();
3558             uidRemovedBroadcastReceiver.assertBroadcastNotReceived();
3559             removedBroadcastReceiver.reset();
3560             // Test uninstall without -k
3561             installPackage(HELLO_WORLD_APK);
3562             uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3563             removedBroadcastReceiver.assertBroadcastReceived();
3564             fullyRemovedBroadcastReceiver.assertBroadcastReceived();
3565             uidRemovedBroadcastReceiver.assertBroadcastReceived();
3566             removedBroadcastReceiver.reset();
3567             fullyRemovedBroadcastReceiver.reset();
3568             uidRemovedBroadcastReceiver.reset();
3569             // Test uninstall --user without -k
3570             installPackage(HELLO_WORLD_APK);
3571             uninstallPackageForUser(HELLO_WORLD_PACKAGE_NAME, testUserId);
3572             removedBroadcastReceiver.assertBroadcastReceived();
3573             fullyRemovedBroadcastReceiver.assertBroadcastReceived();
3574             uidRemovedBroadcastReceiver.assertBroadcastReceived();
3575         } finally {
3576             // Clean up
3577             mContext.unregisterReceiver(removedBroadcastReceiver);
3578             mContext.unregisterReceiver(fullyRemovedBroadcastReceiver);
3579             mContext.unregisterReceiver(uidRemovedBroadcastReceiver);
3580         }
3581     }
3582 
3583     @Test
testReinstallBroadcastsAfterDeleteKeepData()3584     public void testReinstallBroadcastsAfterDeleteKeepData() throws Exception {
3585         installPackage(HELLO_WORLD_APK);
3586         // Test uninstall -k
3587         uninstallPackageKeepData(HELLO_WORLD_PACKAGE_NAME);
3588         final int testUserId = Process.myUserHandle().getIdentifier();
3589         final PackageBroadcastReceiver
3590                 replacedBroadcastReceiver = new PackageBroadcastReceiver(
3591                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_REPLACED
3592         );
3593         final PackageBroadcastReceiver addedBroadcastReceiver = new PackageBroadcastReceiver(
3594                 HELLO_WORLD_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_ADDED
3595         );
3596         final IntentFilter intentFilter = new IntentFilter();
3597         intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
3598         intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
3599         intentFilter.addDataScheme("package");
3600         mContext.registerReceiver(replacedBroadcastReceiver, intentFilter);
3601         mContext.registerReceiver(addedBroadcastReceiver, intentFilter);
3602 
3603         try {
3604             // Reinstall and verify that the correct broadcasts are received
3605             installPackage(HELLO_WORLD_APK);
3606             replacedBroadcastReceiver.assertBroadcastReceived();
3607             final Intent replacedIntent = replacedBroadcastReceiver.getBroadcastResult();
3608             assertThat(replacedIntent).isNotNull();
3609             assertThat(
3610                     replacedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)).isTrue();
3611             addedBroadcastReceiver.assertBroadcastReceived();
3612             final Intent addedIntent = addedBroadcastReceiver.getBroadcastResult();
3613             assertThat(addedIntent).isNotNull();
3614             assertThat(addedIntent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)).isTrue();
3615             // Clean up
3616             uninstallPackage(HELLO_WORLD_PACKAGE_NAME);
3617         } finally {
3618             mContext.unregisterReceiver(replacedBroadcastReceiver);
3619             mContext.unregisterReceiver(addedBroadcastReceiver);
3620         }
3621     }
3622 
3623     @Test
testDeleteSystemApp()3624     public void testDeleteSystemApp() {
3625         PackageInfo ctsShimPackageInfo = null;
3626         try {
3627             ctsShimPackageInfo = mPackageManager.getPackageInfo(
3628                     CTS_SHIM_PACKAGE_NAME, MATCH_SYSTEM_ONLY);
3629         } catch (NameNotFoundException e) {
3630             Log.w(TAG, "Device doesn't have " + CTS_SHIM_PACKAGE_NAME + " installed, skipping");
3631         }
3632         assumeTrue(ctsShimPackageInfo != null);
3633         final int testUserId = Process.myUserHandle().getIdentifier();
3634         try {
3635             // Delete the system package with DELETE_SYSTEM_APP
3636             uninstallPackageForUser(CTS_SHIM_PACKAGE_NAME, testUserId);
3637             assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, testUserId,
3638                     0)).isFalse();
3639             assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, testUserId,
3640                     MATCH_DISABLED_COMPONENTS)).isFalse();
3641             assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, testUserId,
3642                     MATCH_DISABLED_UNTIL_USED_COMPONENTS)).isFalse();
3643             assertThat(matchesInstalled(mPackageManager, CTS_SHIM_PACKAGE_NAME, testUserId,
3644                     MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS)).isTrue();
3645         } finally {
3646             installExistingPackageForUser(CTS_SHIM_PACKAGE_NAME, testUserId);
3647         }
3648     }
3649 
3650     @Test
testInstallSystemAppAsInstant()3651     public void testInstallSystemAppAsInstant() {
3652         PackageInfo ctsShimPackageInfo = null;
3653         try {
3654             ctsShimPackageInfo = mPackageManager.getPackageInfo(
3655                     CTS_SHIM_PACKAGE_NAME, MATCH_SYSTEM_ONLY);
3656         } catch (NameNotFoundException e) {
3657             Log.w(TAG, "Device doesn't have " + CTS_SHIM_PACKAGE_NAME + " installed, skipping");
3658         }
3659         assumeTrue(ctsShimPackageInfo != null);
3660         final int testUserId = Process.myUserHandle().getIdentifier();
3661         try {
3662             // Delete the system package with DELETE_SYSTEM_APP
3663             uninstallPackageForUser(CTS_SHIM_PACKAGE_NAME, testUserId);
3664             String result = SystemUtil.runShellCommand(
3665                     "pm install-existing --instant --user " + testUserId + " "
3666                             + CTS_SHIM_PACKAGE_NAME);
3667             assertThat(result).contains("NameNotFoundException");
3668         } finally {
3669             installExistingPackageForUser(CTS_SHIM_PACKAGE_NAME, testUserId);
3670         }
3671     }
3672 
matchesInstalled(PackageManager pm, String packageName, int userId, long flag)3673     static boolean matchesInstalled(PackageManager pm, String packageName, int userId, long flag) {
3674         List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser(
3675                 PackageManager.PackageInfoFlags.of(flag), userId);
3676         List<String> packageNames = packageInfos.stream()
3677                 .map(p -> p.packageName)
3678                 .toList();
3679         return packageNames.contains(packageName);
3680     }
3681 
3682     @Test
3683     @RequiresFlagsDisabled(FLAG_QUARANTINED_ENABLED)
testQasDisabled()3684     public void testQasDisabled() throws Exception {
3685         testQas(false);
3686     }
3687 
3688     @Test
3689     @RequiresFlagsEnabled(FLAG_QUARANTINED_ENABLED)
testQasEnabled()3690     public void testQasEnabled() throws Exception {
3691         testQas(true);
3692     }
3693 
testQas(boolean enabled)3694     private void testQas(boolean enabled) throws Exception {
3695         installPackage(HELLO_WORLD_APK);
3696         SystemUtil.runWithShellPermissionIdentity(() -> {
3697             String[] notset = mPackageManager.setPackagesSuspended(
3698                     new String[]{HELLO_WORLD_PACKAGE_NAME}, true, null, null, null,
3699                     FLAG_SUSPEND_QUARANTINED);
3700             assertEquals("", String.join(",", notset));
3701         });
3702 
3703         // Flag treatment.
3704         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(HELLO_WORLD_PACKAGE_NAME, 0);
3705         assertTrue(appInfo.enabled);
3706 
3707         // Default filtration of activities.
3708         List<ResolveInfo> activitiesResult;
3709         {
3710             // 1. queryIntentActivities
3711             final Intent intent = new Intent(ACTIVITY_ACTION_NAME);
3712             intent.setPackage(HELLO_WORLD_PACKAGE_NAME);
3713             activitiesResult = mPackageManager.queryIntentActivities(intent,
3714                     PackageManager.ResolveInfoFlags.of(0));
3715             assertEquals(activitiesResult.toString(), 1, activitiesResult.size());
3716             assertEquals("com.example.helloworld.MainActivity",
3717                     activitiesResult.get(0).activityInfo.name);
3718 
3719             // 2. getActivityInfo
3720             var componentInfo = activitiesResult.get(0).getComponentInfo();
3721             var activityInfo = mPackageManager.getActivityInfo(
3722                     new ComponentName(componentInfo.packageName, componentInfo.name),
3723                     PackageManager.ComponentInfoFlags.of(0));
3724             assertNotNull(activityInfo);
3725             assertEquals(activityInfo.name, activitiesResult.get(0).activityInfo.name);
3726 
3727             // 3. PackageManager.getPackageInfo(<PKG>, GET_ACTIVITIES)
3728             var packageInfo = mPackageManager.getPackageInfo(HELLO_WORLD_PACKAGE_NAME,
3729                     PackageManager.PackageInfoFlags.of(GET_ACTIVITIES));
3730             assertEquals(1, packageInfo.activities.length);
3731             assertEquals("com.example.helloworld.MainActivity", packageInfo.activities[0].name);
3732 
3733             // 4. mPackageManager.getInstalledPackages(GET_ACTIVITIES);
3734             List<PackageInfo> pkgs = mPackageManager.getInstalledPackages(
3735                     PackageManager.PackageInfoFlags.of(GET_ACTIVITIES));
3736             PackageInfo pkgInfo = findPackageOrFail(pkgs, HELLO_WORLD_PACKAGE_NAME);
3737             assertEquals(1, pkgInfo.activities.length);
3738             assertEquals("com.example.helloworld.MainActivity", pkgInfo.activities[0].name);
3739         }
3740 
3741         // Default filtration of services.
3742         List<ResolveInfo> servicesResult;
3743         {
3744             Intent intent = new Intent("com.example.helloworld.service");
3745             intent.setPackage(HELLO_WORLD_PACKAGE_NAME);
3746             servicesResult = mPackageManager.queryIntentServices(intent, 0);
3747             if (servicesResult == null) {
3748                 servicesResult = new ArrayList<>();
3749             }
3750         }
3751 
3752         // Match QAS services.
3753         List<ResolveInfo> servicesResult1;
3754         {
3755             Intent intent = new Intent("com.example.helloworld.service");
3756             intent.setPackage(HELLO_WORLD_PACKAGE_NAME);
3757             servicesResult1 = mPackageManager.queryIntentServices(intent,
3758                     PackageManager.ResolveInfoFlags.of(MATCH_QUARANTINED_COMPONENTS));
3759             if (servicesResult1 == null) {
3760                 servicesResult1 = new ArrayList<>();
3761             }
3762             assertEquals(servicesResult1.toString(), 1, servicesResult1.size());
3763             assertEquals("com.example.helloworld.TestService",
3764                     servicesResult1.get(0).serviceInfo.name);
3765         }
3766 
3767         // Default filtration of providers.
3768         final List<ResolveInfo> providersResult1;
3769         {
3770             Intent intent = new Intent("com.example.helloworld.provider");
3771             intent.setPackage(HELLO_WORLD_PACKAGE_NAME);
3772             intent.setComponent(new ComponentName(HELLO_WORLD_PACKAGE_NAME,
3773                     "com.example.helloworld.TestContentProvider"));
3774             providersResult1 = mPackageManager.queryIntentContentProviders(intent, 0);
3775         }
3776 
3777         final List<ResolveInfo> providersResult2;
3778         {
3779             Intent intent = new Intent("com.example.helloworld.provider");
3780             providersResult2 = mPackageManager.queryIntentContentProviders(intent, 0);
3781         }
3782 
3783         final List<ResolveInfo> providersResult3;
3784         {
3785             Intent intent = new Intent("com.example.helloworld.provider");
3786             intent.setPackage(HELLO_WORLD_PACKAGE_NAME);
3787             providersResult3 = mPackageManager.queryIntentContentProviders(intent, 0);
3788         }
3789 
3790         ProviderInfo contentProvider = mPackageManager.resolveContentProvider(
3791                 "com.example.helloworld.testcontentprovider", 0);
3792 
3793         boolean providerFound = false;
3794         {
3795             final List<ProviderInfo> result = mPackageManager.queryContentProviders(null, 0, 0);
3796             for (int i = 0, size = result == null ? 0 : result.size(); i < size;
3797                     ++i) {
3798                 final ProviderInfo providerInfo = result.get(i);
3799                 if ("com.example.helloworld.TestContentProvider".equals(providerInfo.name)) {
3800                     providerFound = true;
3801                     break;
3802                 }
3803             }
3804         }
3805 
3806         if (enabled) {
3807             assertTrue(isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3808             assertTrue(servicesResult.toString(), servicesResult.size() == 0);
3809             assertTrue(providersResult1.toString(), providersResult1.size() == 0);
3810             assertTrue(providersResult2.toString(), providersResult2.size() == 0);
3811             assertTrue(providersResult3.toString(), providersResult3.size() == 0);
3812             assertFalse(providerFound);
3813         } else {
3814             assertFalse(isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3815             assertEquals(servicesResult.toString(), 1, servicesResult.size());
3816             assertEquals("com.example.helloworld.TestService",
3817                     servicesResult.get(0).serviceInfo.name);
3818             assertEquals(providersResult1.toString(), 1, providersResult1.size());
3819             assertEquals("com.example.helloworld.TestContentProvider",
3820                     providersResult1.get(0).providerInfo.name);
3821             assertEquals(providersResult2.toString(), 1, providersResult2.size());
3822             assertEquals("com.example.helloworld.TestContentProvider",
3823                     providersResult2.get(0).providerInfo.name);
3824             assertEquals(providersResult3.toString(), 1, providersResult3.size());
3825             assertEquals("com.example.helloworld.TestContentProvider",
3826                     providersResult3.get(0).providerInfo.name);
3827             assertNotNull(contentProvider);
3828             assertEquals("com.example.helloworld.TestContentProvider",
3829                     contentProvider.name);
3830             assertTrue(providerFound);
3831         }
3832     }
3833 
3834     @Test
3835     @RequiresFlagsEnabled(FLAG_QUARANTINED_ENABLED)
testQasPrecedence()3836     public void testQasPrecedence() throws Exception {
3837         var ctsPackageName = mContext.getPackageName();
3838         var userId = mContext.getUserId();
3839 
3840         installPackage(HELLO_WORLD_APK);
3841 
3842         // Suspend by shell.
3843         SystemUtil.runShellCommand("pm suspend --user " + userId + " " + HELLO_WORLD_PACKAGE_NAME);
3844         assertTrue("package is suspended by shell", isPackageSuspended(HELLO_WORLD_PACKAGE_NAME));
3845         assertFalse("package is not quarantined", isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3846 
3847         // QAS as cts.
3848         var builder = new SuspendDialogInfo.Builder();
3849         builder.setTitle("qas-ed by cts");
3850         builder.setMessage("test message");
3851         builder.setNeutralButtonText("test neutral message");
3852         var dialogInfo = builder.build();
3853 
3854         SystemUtil.runWithShellPermissionIdentity(() -> {
3855             String[] notset = mPackageManager.setPackagesSuspended(
3856                     new String[]{HELLO_WORLD_PACKAGE_NAME}, true,
3857                     null, null, dialogInfo, FLAG_SUSPEND_QUARANTINED);
3858             assertEquals("", String.join(",", notset));
3859         }, QUARANTINE_APPS);
3860         assertTrue("package is quarantined by both shell and cts",
3861                 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3862         assertEquals(ctsPackageName,
3863                 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME));
3864 
3865         // Un-suspend as shell.
3866         SystemUtil.runShellCommand("pm unsuspend --user " + userId + " "
3867                 + HELLO_WORLD_PACKAGE_NAME);
3868         assertTrue("package is still quarantined by cts",
3869                 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3870         // Still "cts" package.
3871         assertEquals(ctsPackageName,
3872                 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME));
3873 
3874         // No effect.
3875         SystemUtil.runShellCommand("pm unsuspend --user " + userId + " "
3876                 + HELLO_WORLD_PACKAGE_NAME);
3877         assertTrue("package is still quarantined by cts",
3878                 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3879         assertEquals(ctsPackageName,
3880                 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME));
3881 
3882         // QAS as shell.
3883         SystemUtil.runShellCommand("pm suspend-quarantine --dialogMessage shell-message "
3884                 + "--user " + userId + " " + HELLO_WORLD_PACKAGE_NAME);
3885         assertTrue("package is quarantined by shell and cts",
3886                 isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3887 
3888         // Un-quarantine by cts.
3889         SystemUtil.runWithShellPermissionIdentity(() -> {
3890             String[] notset =
3891                     mPackageManager.setPackagesSuspended(new String[]{HELLO_WORLD_PACKAGE_NAME},
3892                             false, null, null, null, FLAG_SUSPEND_QUARANTINED);
3893             assertEquals("", String.join(",", notset));
3894         }, QUARANTINE_APPS);
3895         assertEquals("com.android.shell",
3896                 mPackageManager.getSuspendingPackage(HELLO_WORLD_PACKAGE_NAME));
3897 
3898         // Unsuspend by shell.
3899         SystemUtil.runShellCommand("pm unsuspend --user " + userId + " "
3900                 + HELLO_WORLD_PACKAGE_NAME);
3901         assertFalse("not quarantined anymore", isPackageQuarantined(HELLO_WORLD_PACKAGE_NAME));
3902     }
3903 
3904     @Test
3905     @RequiresFlagsEnabled(FLAG_RESTRICT_NONPRELOADS_SYSTEM_SHAREDUIDS)
testUidRemovedBroadcastNotReceivedForSharedUid()3906     public void testUidRemovedBroadcastNotReceivedForSharedUid() throws Exception {
3907         // Installing a test app that shares SYSTEM_UID
3908         var result = SystemUtil.runShellCommand("pm install -t -g " + HELLO_WORLD_SETTINGS);
3909         if (result.contains("no signatures that match those in shared user android.uid.system")) {
3910             // This test only works if platform and cts are built using the same certificate.
3911             return;
3912         }
3913         if (!Build.IS_DEBUGGABLE) {
3914             // Non-debuggable builds don't allow non-preloaded apps that use system certificate.
3915             return;
3916         }
3917         assertThat(result).isEqualTo("Success\n");
3918         assertTrue(isPackagePresent(HELLO_WORLD_SETTINGS_PACKAGE_NAME));
3919         int testUserId = Process.myUserHandle().getIdentifier();
3920         PackageBroadcastReceiver packageRemovedBroadcastReceiver = new PackageBroadcastReceiver(
3921                 HELLO_WORLD_SETTINGS_PACKAGE_NAME, testUserId, Intent.ACTION_PACKAGE_REMOVED
3922         );
3923         final IntentFilter packageRemovedIntentFilter =
3924                 new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
3925         packageRemovedIntentFilter.addDataScheme("package");
3926         PackageBroadcastReceiver uidRemovedBroadcastReceiver = new PackageBroadcastReceiver(
3927                 HELLO_WORLD_SETTINGS_PACKAGE_NAME, testUserId, Intent.ACTION_UID_REMOVED
3928         );
3929         final IntentFilter uidRemovedIntentFilter = new IntentFilter(Intent.ACTION_UID_REMOVED);
3930         mContext.registerReceiver(packageRemovedBroadcastReceiver, packageRemovedIntentFilter);
3931         mContext.registerReceiver(uidRemovedBroadcastReceiver, uidRemovedIntentFilter);
3932 
3933         try {
3934             uninstallPackage(HELLO_WORLD_SETTINGS_PACKAGE_NAME);
3935             packageRemovedBroadcastReceiver.assertBroadcastReceived();
3936             uidRemovedBroadcastReceiver.assertBroadcastNotReceived();
3937         } finally {
3938             mContext.unregisterReceiver(packageRemovedBroadcastReceiver);
3939             mContext.unregisterReceiver(uidRemovedBroadcastReceiver);
3940         }
3941     }
3942 
3943     @Test
3944     @RequiresFlagsEnabled(FLAG_CLOUD_COMPILATION_PM)
testGetVerifiedSigningInfo()3945     public void testGetVerifiedSigningInfo() throws Exception {
3946         SigningInfo signingInfo = mPackageManager.getVerifiedSigningInfo(
3947                 EMPTY_APP_APK, SigningInfo.VERSION_SIGNING_BLOCK_V3);
3948         assertThat(signingInfo.getSigningCertificateHistory()).isNotEmpty();
3949     }
3950 
3951     @Test
3952     @RequiresFlagsEnabled(FLAG_CLOUD_COMPILATION_PM)
testGetVerifiedSigningInfoError()3953     public void testGetVerifiedSigningInfoError() throws Exception {
3954         var e = expectThrows(SigningInfoException.class, () -> {
3955             mPackageManager.getVerifiedSigningInfo(
3956                 EMPTY_APP_APK, SigningInfo.VERSION_SIGNING_BLOCK_V4);
3957         });
3958         assertThat(e.getCode()).isEqualTo(PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES);
3959     }
3960 
isPackageSuspended(String packageName)3961     private boolean isPackageSuspended(String packageName) {
3962         return SystemUtil.runWithShellPermissionIdentity(
3963                 () -> mPackageManager.isPackageSuspended(packageName));
3964     }
3965 
isPackageQuarantined(String packageName)3966     private boolean isPackageQuarantined(String packageName) {
3967         return SystemUtil.runWithShellPermissionIdentity(
3968                 () -> mPackageManager.isPackageQuarantined(packageName));
3969     }
3970 
sendIntent(IntentSender intentSender)3971     private void sendIntent(IntentSender intentSender) throws IntentSender.SendIntentException {
3972         intentSender.sendIntent(mContext, 0 /* code */, null /* intent */,
3973                 null /* requiredPermission */,
3974                 ActivityOptions.makeBasic().setPendingIntentBackgroundActivityStartMode(
3975                         ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED).toBundle(),
3976                 null /* handler */, null /* onFinished */);
3977     }
3978 
getInstalledState(String packageName, int userId)3979     static String getInstalledState(String packageName, int userId) {
3980         final String commandResult = SystemUtil.runShellCommand("pm dump " + packageName);
3981         final String userStatesLine = Arrays.stream(commandResult.split("\\r?\\n"))
3982                 .filter(line -> line.startsWith("    User " + userId + ":"))
3983                 .findFirst()
3984                 .orElse(null);
3985         if (userStatesLine == null) {
3986             return null;
3987         }
3988         final String key = "installed=";
3989         final int keyStart = userStatesLine.indexOf(key);
3990         if (keyStart < 0) {
3991             return null;
3992         }
3993         final int keyEnd = userStatesLine.indexOf(key) + key.length();
3994         final int valueEnd = userStatesLine.indexOf(" ", keyEnd);
3995         return userStatesLine.substring(keyEnd, valueEnd);
3996     }
3997 
3998     @Test
3999     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO)
testParseAndroidManifest_withNullApkFile()4000     public void testParseAndroidManifest_withNullApkFile() {
4001         // Disallow the apk file is null
4002         assertThrows(NullPointerException.class,
4003                 () -> mPackageManager.parseAndroidManifest((File) null /* apkFile */,
4004                         xmlResourceParser -> new Bundle()));
4005     }
4006 
4007     @Test
4008     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO)
testParseAndroidManifest_withNullParserFunction()4009     public void testParseAndroidManifest_withNullParserFunction() {
4010         // Disallow the parser function is null
4011         assertThrows(NullPointerException.class,
4012                 () -> mPackageManager.parseAndroidManifest(new File(mContext.getPackageCodePath()),
4013                         null /* parserFunction */));
4014     }
4015 
4016     @Test
4017     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO)
testParseAndroidManifest_withInvalidApkFile()4018     public void testParseAndroidManifest_withInvalidApkFile() {
4019         assertThrows(IOException.class,
4020                 () -> mPackageManager.parseAndroidManifest(new File("/data/app/invalid/base.apk"),
4021                         xmlResourceParser -> new Bundle()));
4022     }
4023 
4024     @Test
4025     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO)
testParseAndroidManifest()4026     public void testParseAndroidManifest() {
4027         Bundle testResult;
4028         try {
4029             testResult = mPackageManager.parseAndroidManifest(
4030                     new File(mContext.getPackageCodePath()),
4031                     xmlResourceParser -> {
4032                         assertNotNull(xmlResourceParser);
4033 
4034                         // Search the start tag
4035                         int type = -1;
4036                         try {
4037                             while ((type = xmlResourceParser.next()) != XmlPullParser.START_TAG
4038                                     && type != XmlPullParser.END_DOCUMENT) {
4039                                 Log.d(TAG, "type=" + type);
4040                             }
4041                         } catch (Exception e) {
4042                             Log.e(TAG, "Failure to parse next" + e);
4043                         }
4044 
4045                         assertThat(type).isEqualTo(XmlPullParser.START_TAG);
4046                         assertThat(xmlResourceParser.getName()).isEqualTo(TAG_MANIFEST);
4047                         assertThat(xmlResourceParser.getAttributeValue(null, "package")).isEqualTo(
4048                                 PACKAGE_NAME);
4049 
4050                         Bundle bundle = new Bundle();
4051                         bundle.putString("package", PACKAGE_NAME);
4052                         return bundle;
4053                     });
4054         } catch (IOException e) {
4055             Log.e(TAG, "Failure to parse android manifest" + e);
4056             testResult = null;
4057         }
4058 
4059         assertNotNull(testResult);
4060         assertThat(testResult.getString("package")).isEqualTo(PACKAGE_NAME);
4061     }
4062 
4063     @Test
4064     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD)
testParseAndroidManifestWithFd_withNullApkFileDescriptor()4065     public void testParseAndroidManifestWithFd_withNullApkFileDescriptor() {
4066         // Disallow the apk fd is null
4067         assertThrows(NullPointerException.class,
4068                 () -> mPackageManager.parseAndroidManifest((ParcelFileDescriptor) null,
4069                         xmlResourceParser -> new Bundle()));
4070     }
4071 
4072     @Test
4073     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD)
testParseAndroidManifestWithFd_withNullParserFunction()4074     public void testParseAndroidManifestWithFd_withNullParserFunction() {
4075         // Disallow the parser function is null
4076         assertThrows(NullPointerException.class,
4077                 () -> mPackageManager.parseAndroidManifest(
4078                         ParcelFileDescriptor.open(new File(
4079                                 mContext.getPackageCodePath()),
4080                                 ParcelFileDescriptor.MODE_READ_ONLY),
4081                         null /* parserFunction */));
4082     }
4083 
4084     @Test
4085     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD)
testParseAndroidManifestWithFd_withInvalidApkFile()4086     public void testParseAndroidManifestWithFd_withInvalidApkFile() {
4087         assertThrows(IOException.class,
4088                 () -> mPackageManager.parseAndroidManifest(
4089                         ParcelFileDescriptor.open(new File("/data/app/invalid/base.apk"),
4090                                 ParcelFileDescriptor.MODE_READ_ONLY),
4091                         xmlResourceParser -> new Bundle()));
4092     }
4093 
4094     @Test
4095     @RequiresFlagsEnabled(FLAG_GET_PACKAGE_INFO_WITH_FD)
testParseAndroidManifestWithFd()4096     public void testParseAndroidManifestWithFd() {
4097         Bundle testResult;
4098         try {
4099             testResult = mPackageManager.parseAndroidManifest(
4100                     ParcelFileDescriptor.open(new File(mContext.getPackageCodePath()),
4101                             ParcelFileDescriptor.MODE_READ_ONLY),
4102                     xmlResourceParser -> {
4103                         assertNotNull(xmlResourceParser);
4104 
4105                         // Search the start tag
4106                         int type = -1;
4107                         try {
4108                             while ((type = xmlResourceParser.next()) != XmlPullParser.START_TAG
4109                                     && type != XmlPullParser.END_DOCUMENT) {
4110                                 Log.d(TAG, "type=" + type);
4111                             }
4112                         } catch (Exception e) {
4113                             Log.e(TAG, "Failure to parse next" + e);
4114                         }
4115 
4116                         assertThat(type).isEqualTo(XmlPullParser.START_TAG);
4117                         assertThat(xmlResourceParser.getName()).isEqualTo(TAG_MANIFEST);
4118                         assertThat(xmlResourceParser.getAttributeValue(null, "package")).isEqualTo(
4119                                 PACKAGE_NAME);
4120 
4121                         Bundle bundle = new Bundle();
4122                         bundle.putString("package", PACKAGE_NAME);
4123                         return bundle;
4124                     });
4125         } catch (IOException e) {
4126             Log.e(TAG, "Failure to parse android manifest" + e);
4127             testResult = null;
4128         }
4129 
4130         assertNotNull(testResult);
4131         assertThat(testResult.getString("package")).isEqualTo(PACKAGE_NAME);
4132     }
4133 
4134     @Test
4135     @RequiresFlagsEnabled(FLAG_MIN_TARGET_SDK_24)
4136     @CddTest(requirements = {"3.1/C-0-8"})
testInstallTargetSdk23Fail()4137     public void testInstallTargetSdk23Fail() {
4138         assertThat(installPackageWithResult(CTS_TARGET_SDK_23)).contains(
4139                 "INSTALL_FAILED_DEPRECATED_SDK_VERSION");
4140         assertThat(installPackage(CTS_TARGET_SDK_24)).isTrue();
4141     }
4142 
4143     @Test
4144     @RequiresFlagsEnabled(FLAG_MIN_TARGET_SDK_24)
4145     @CddTest(requirements = {"3.1/C-0-8"})
testInstallTargetSdk23Bypass()4146     public void testInstallTargetSdk23Bypass() {
4147         String result = SystemUtil.runShellCommand(
4148                 "pm install -t -g --bypass-low-target-sdk-block " + CTS_TARGET_SDK_23);
4149         assertThat(result).isEqualTo("Success\n");
4150         assertThat(installPackage(CTS_TARGET_SDK_24)).isTrue();
4151     }
4152 
4153     @Test
4154     @RequiresFlagsDisabled(FLAG_MIN_TARGET_SDK_24)
4155     @CddTest(requirements = {"3.1/C-0-8"})
testInstallTargetSdk23Success()4156     public void testInstallTargetSdk23Success() {
4157         assertThat(installPackage(CTS_TARGET_SDK_23)).isTrue();
4158         assertThat(installPackage(CTS_TARGET_SDK_24)).isTrue();
4159     }
4160 
setUpdateMimeGroupAndAssertBroadcasts(Set<String> mimeTypes, boolean isBroadcastReceived)4161     private void setUpdateMimeGroupAndAssertBroadcasts(Set<String> mimeTypes,
4162             boolean isBroadcastReceived) throws Exception {
4163         final String expectedPackageName = mContext.getPackageName();
4164         final IntentFilter filter = new IntentFilter();
4165         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
4166         filter.addDataScheme("package");
4167         final PackageBroadcastReceiver packageChangedBroadcastReceiver =
4168                 new PackageBroadcastReceiver(expectedPackageName,
4169                         Process.myUserHandle().getIdentifier(), Intent.ACTION_PACKAGE_CHANGED);
4170         mContext.registerReceiver(packageChangedBroadcastReceiver, filter, RECEIVER_EXPORTED);
4171         try {
4172             mPackageManager.setMimeGroup(MIME_GROUP, mimeTypes);
4173             if (isBroadcastReceived) {
4174                 packageChangedBroadcastReceiver.assertBroadcastReceived();
4175                 final Intent resultIntent = packageChangedBroadcastReceiver.getBroadcastResult();
4176                 final String[] receivedComponents = resultIntent.getStringArrayExtra(
4177                         Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
4178                 assertThat(receivedComponents).isNotNull();
4179                 assertThat(receivedComponents[0]).isEqualTo(expectedPackageName);
4180                 assertThat(mPackageManager.getMimeGroup(MIME_GROUP)).isEqualTo(mimeTypes);
4181             } else {
4182                 packageChangedBroadcastReceiver.assertBroadcastNotReceived();
4183             }
4184         } finally {
4185             mContext.unregisterReceiver(packageChangedBroadcastReceiver);
4186         }
4187     }
4188 
4189     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
4190             codeName = "VanillaIceCream")
4191     @Test
testUpdateMimeGroup_changed()4192     public void testUpdateMimeGroup_changed() throws Exception {
4193         Set<String> mimeTypes = Collections.singleton("text/*");
4194 
4195         setUpdateMimeGroupAndAssertBroadcasts(mimeTypes, /* isBroadcastReceived= */ true);
4196         assertThat(mPackageManager.getMimeGroup(MIME_GROUP)).isEqualTo(mimeTypes);
4197     }
4198 
4199     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
4200             codeName = "VanillaIceCream")
4201     @Test
testUpdateMimeGroup_noChanged_noBroadcastReceived()4202     public void testUpdateMimeGroup_noChanged_noBroadcastReceived() throws Exception {
4203         final Set<String> mimeTypes = Collections.singleton("image/*");
4204 
4205         setUpdateMimeGroupAndAssertBroadcasts(mimeTypes, /* isBroadcastReceived= */ true);
4206         assertThat(mPackageManager.getMimeGroup(MIME_GROUP)).isEqualTo(mimeTypes);
4207         setUpdateMimeGroupAndAssertBroadcasts(mimeTypes, /* isBroadcastReceived= */ false);
4208     }
4209 }
4210