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