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