1 /*
2  * Copyright (C) 2019 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.appenumeration.cts;
18 
19 import static android.Manifest.permission.SET_PREFERRED_APPLICATIONS;
20 import static android.appenumeration.cts.Constants.ACTION_AWAIT_LAUNCHER_APPS_CALLBACK;
21 import static android.appenumeration.cts.Constants.ACTION_BIND_SERVICE;
22 import static android.appenumeration.cts.Constants.ACTION_CHECK_SIGNATURES;
23 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES;
24 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS;
25 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_PACKAGES;
26 import static android.appenumeration.cts.Constants.ACTION_GET_NAMES_FOR_UIDS;
27 import static android.appenumeration.cts.Constants.ACTION_GET_NAME_FOR_UID;
28 import static android.appenumeration.cts.Constants.ACTION_GET_PACKAGES_FOR_UID;
29 import static android.appenumeration.cts.Constants.ACTION_GET_PACKAGE_INFO;
30 import static android.appenumeration.cts.Constants.ACTION_GET_PREFERRED_ACTIVITIES;
31 import static android.appenumeration.cts.Constants.ACTION_GET_SHAREDLIBRARY_DEPENDENT_PACKAGES;
32 import static android.appenumeration.cts.Constants.ACTION_GET_SYNCADAPTER_PACKAGES_FOR_AUTHORITY;
33 import static android.appenumeration.cts.Constants.ACTION_GET_SYNCADAPTER_TYPES;
34 import static android.appenumeration.cts.Constants.ACTION_HAS_SIGNING_CERTIFICATE;
35 import static android.appenumeration.cts.Constants.ACTION_JUST_FINISH;
36 import static android.appenumeration.cts.Constants.ACTION_LAUNCHER_APPS_IS_ACTIVITY_ENABLED;
37 import static android.appenumeration.cts.Constants.ACTION_MANIFEST_ACTIVITY;
38 import static android.appenumeration.cts.Constants.ACTION_MANIFEST_PROVIDER;
39 import static android.appenumeration.cts.Constants.ACTION_MANIFEST_SERVICE;
40 import static android.appenumeration.cts.Constants.ACTION_QUERY_ACTIVITIES;
41 import static android.appenumeration.cts.Constants.ACTION_QUERY_PROVIDERS;
42 import static android.appenumeration.cts.Constants.ACTION_QUERY_RESOLVER;
43 import static android.appenumeration.cts.Constants.ACTION_QUERY_SERVICES;
44 import static android.appenumeration.cts.Constants.ACTION_SET_INSTALLER_PACKAGE_NAME;
45 import static android.appenumeration.cts.Constants.ACTION_START_DIRECTLY;
46 import static android.appenumeration.cts.Constants.ACTION_START_FOR_RESULT;
47 import static android.appenumeration.cts.Constants.ACTIVITY_CLASS_DUMMY_ACTIVITY;
48 import static android.appenumeration.cts.Constants.ACTIVITY_CLASS_TEST;
49 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_INVALID;
50 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_SUSPENDED;
51 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_UNSUSPENDED;
52 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_ADDED;
53 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_CHANGED;
54 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_REMOVED;
55 import static android.appenumeration.cts.Constants.EXTRA_AUTHORITY;
56 import static android.appenumeration.cts.Constants.EXTRA_CERT;
57 import static android.appenumeration.cts.Constants.EXTRA_DATA;
58 import static android.appenumeration.cts.Constants.EXTRA_ERROR;
59 import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
60 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK;
61 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_READY_CALLBACK;
62 import static android.appenumeration.cts.Constants.QUERIES_ACTIVITY_ACTION;
63 import static android.appenumeration.cts.Constants.QUERIES_NOTHING;
64 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PERM;
65 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PROVIDER;
66 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_Q;
67 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_PERM_URI;
68 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_RECEIVES_URI;
69 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SEES_INSTALLER;
70 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SEES_INSTALLER_APK;
71 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SHARED_USER;
72 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_USES_LIBRARY;
73 import static android.appenumeration.cts.Constants.QUERIES_NOTHING_USES_OPTIONAL_LIBRARY;
74 import static android.appenumeration.cts.Constants.QUERIES_PACKAGE;
75 import static android.appenumeration.cts.Constants.QUERIES_PROVIDER_ACTION;
76 import static android.appenumeration.cts.Constants.QUERIES_PROVIDER_AUTH;
77 import static android.appenumeration.cts.Constants.QUERIES_SERVICE_ACTION;
78 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_ACTIVITY_ACTION;
79 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_PROVIDER_ACTION;
80 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_PROVIDER_AUTH;
81 import static android.appenumeration.cts.Constants.QUERIES_UNEXPORTED_SERVICE_ACTION;
82 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_ACTION;
83 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_BROWSABLE;
84 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_BROWSER;
85 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_CONTACTS;
86 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_EDITOR;
87 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_SHARE;
88 import static android.appenumeration.cts.Constants.QUERIES_WILDCARD_WEB;
89 import static android.appenumeration.cts.Constants.TARGET_APPWIDGETPROVIDER;
90 import static android.appenumeration.cts.Constants.TARGET_APPWIDGETPROVIDER_SHARED_USER;
91 import static android.appenumeration.cts.Constants.TARGET_BROWSER;
92 import static android.appenumeration.cts.Constants.TARGET_BROWSER_WILDCARD;
93 import static android.appenumeration.cts.Constants.TARGET_CONTACTS;
94 import static android.appenumeration.cts.Constants.TARGET_EDITOR;
95 import static android.appenumeration.cts.Constants.TARGET_FILTERS;
96 import static android.appenumeration.cts.Constants.TARGET_FILTERS_APK;
97 import static android.appenumeration.cts.Constants.TARGET_FORCEQUERYABLE;
98 import static android.appenumeration.cts.Constants.TARGET_FORCEQUERYABLE_NORMAL;
99 import static android.appenumeration.cts.Constants.TARGET_NO_API;
100 import static android.appenumeration.cts.Constants.TARGET_PREFERRED_ACTIVITY;
101 import static android.appenumeration.cts.Constants.TARGET_SHARE;
102 import static android.appenumeration.cts.Constants.TARGET_SHARED_LIBRARY_PACKAGE;
103 import static android.appenumeration.cts.Constants.TARGET_SHARED_USER;
104 import static android.appenumeration.cts.Constants.TARGET_STUB;
105 import static android.appenumeration.cts.Constants.TARGET_STUB_APK;
106 import static android.appenumeration.cts.Constants.TARGET_SYNCADAPTER;
107 import static android.appenumeration.cts.Constants.TARGET_SYNCADAPTER_SHARED_USER;
108 import static android.appenumeration.cts.Constants.TARGET_WEB;
109 import static android.content.Intent.EXTRA_PACKAGES;
110 import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES;
111 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
112 import static android.content.pm.PackageManager.SIGNATURE_MATCH;
113 import static android.content.pm.PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
114 import static android.os.Process.INVALID_UID;
115 
116 import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
117 
118 import static org.hamcrest.MatcherAssert.assertThat;
119 import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
120 import static org.hamcrest.Matchers.containsString;
121 import static org.hamcrest.Matchers.emptyArray;
122 import static org.hamcrest.Matchers.equalTo;
123 import static org.hamcrest.Matchers.greaterThan;
124 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
125 import static org.hamcrest.Matchers.hasItemInArray;
126 import static org.hamcrest.Matchers.not;
127 import static org.hamcrest.Matchers.notNullValue;
128 import static org.hamcrest.core.Is.is;
129 import static org.junit.Assert.assertFalse;
130 import static org.junit.Assert.assertThrows;
131 import static org.junit.Assert.assertTrue;
132 import static org.junit.Assert.fail;
133 
134 import android.app.PendingIntent;
135 import android.appwidget.AppWidgetProviderInfo;
136 import android.content.ComponentName;
137 import android.content.Intent;
138 import android.content.IntentFilter;
139 import android.content.SyncAdapterType;
140 import android.content.pm.PackageInfo;
141 import android.content.pm.PackageManager;
142 import android.content.pm.Signature;
143 import android.content.res.Resources;
144 import android.net.Uri;
145 import android.os.Bundle;
146 import android.os.ConditionVariable;
147 import android.os.Handler;
148 import android.os.HandlerThread;
149 import android.os.Parcelable;
150 import android.os.Process;
151 import android.os.RemoteCallback;
152 
153 import androidx.annotation.Nullable;
154 import androidx.test.ext.junit.runners.AndroidJUnit4;
155 import androidx.test.platform.app.InstrumentationRegistry;
156 
157 import com.android.compatibility.common.util.SystemUtil;
158 import com.android.compatibility.common.util.AmUtils;
159 
160 import org.hamcrest.core.IsNull;
161 import org.junit.AfterClass;
162 import org.junit.Assert;
163 import org.junit.BeforeClass;
164 import org.junit.Rule;
165 import org.junit.Test;
166 import org.junit.rules.TestName;
167 import org.junit.runner.RunWith;
168 
169 import java.io.ByteArrayInputStream;
170 import java.io.InputStream;
171 import java.security.cert.Certificate;
172 import java.security.cert.CertificateFactory;
173 import java.security.cert.X509Certificate;
174 import java.util.ArrayList;
175 import java.util.Arrays;
176 import java.util.List;
177 import java.util.Objects;
178 import java.util.UUID;
179 import java.util.concurrent.TimeUnit;
180 import java.util.concurrent.TimeoutException;
181 import java.util.concurrent.atomic.AtomicReference;
182 
183 @RunWith(AndroidJUnit4.class)
184 public class AppEnumerationTests {
185     private static Handler sResponseHandler;
186     private static HandlerThread sResponseThread;
187 
188     private static boolean sGlobalFeatureEnabled;
189 
190     private static PackageManager sPm;
191 
192     // The shared library for getting dependent packages
193     private static final String TEST_SHARED_LIB_NAME = "android.test.runner";
194 
195     @Rule
196     public TestName name = new TestName();
197 
198     @BeforeClass
setup()199     public static void setup() {
200         final String deviceConfigResponse =
201                 SystemUtil.runShellCommand(
202                         "device_config get package_manager_service "
203                                 + "package_query_filtering_enabled")
204                         .trim();
205         if ("null".equalsIgnoreCase(deviceConfigResponse) || deviceConfigResponse.isEmpty()) {
206             sGlobalFeatureEnabled = true;
207         } else {
208             sGlobalFeatureEnabled = Boolean.parseBoolean(deviceConfigResponse);
209         }
210         System.out.println("Feature enabled: " + sGlobalFeatureEnabled);
211         if (!sGlobalFeatureEnabled) return;
212 
213         sResponseThread = new HandlerThread("response");
214         sResponseThread.start();
215         sResponseHandler = new Handler(sResponseThread.getLooper());
216 
217         sPm = InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
218     }
219 
220     @AfterClass
tearDown()221     public static void tearDown() {
222         if (!sGlobalFeatureEnabled) return;
223         sResponseThread.quit();
224     }
225 
226     @Test
systemPackagesQueryable_notEnabled()227     public void systemPackagesQueryable_notEnabled() throws Exception {
228         final Resources resources = Resources.getSystem();
229         assertFalse(
230                 "config_forceSystemPackagesQueryable must not be true.",
231                 resources.getBoolean(resources.getIdentifier(
232                         "config_forceSystemPackagesQueryable", "bool", "android")));
233 
234         // now let's assert that that the actual set of system apps is limited
235         assertThat("Not all system apps should be visible.",
236                 getInstalledPackages(QUERIES_NOTHING_PERM, MATCH_SYSTEM_ONLY).length,
237                 greaterThan(getInstalledPackages(QUERIES_NOTHING, MATCH_SYSTEM_ONLY).length));
238     }
239 
240     @Test
all_canSeeForceQueryable()241     public void all_canSeeForceQueryable() throws Exception {
242         assertVisible(QUERIES_NOTHING, TARGET_FORCEQUERYABLE);
243         assertVisible(QUERIES_ACTIVITY_ACTION, TARGET_FORCEQUERYABLE);
244         assertVisible(QUERIES_SERVICE_ACTION, TARGET_FORCEQUERYABLE);
245         assertVisible(QUERIES_PROVIDER_AUTH, TARGET_FORCEQUERYABLE);
246         assertVisible(QUERIES_PACKAGE, TARGET_FORCEQUERYABLE);
247     }
248 
249     @Test
all_cannotSeeForceQueryableInstalledNormally()250     public void all_cannotSeeForceQueryableInstalledNormally() throws Exception {
251         assertNotVisible(QUERIES_NOTHING, TARGET_FORCEQUERYABLE_NORMAL);
252         assertNotVisible(QUERIES_ACTIVITY_ACTION, TARGET_FORCEQUERYABLE_NORMAL);
253         assertNotVisible(QUERIES_SERVICE_ACTION, TARGET_FORCEQUERYABLE_NORMAL);
254         assertNotVisible(QUERIES_PROVIDER_AUTH, TARGET_FORCEQUERYABLE_NORMAL);
255         assertNotVisible(QUERIES_PACKAGE, TARGET_FORCEQUERYABLE_NORMAL);
256     }
257 
258     @Test
startExplicitly_canStartNonVisible()259     public void startExplicitly_canStartNonVisible() throws Exception {
260         assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS);
261         startExplicitIntentViaComponent(QUERIES_NOTHING, TARGET_FILTERS);
262         startExplicitIntentViaPackageName(QUERIES_NOTHING, TARGET_FILTERS);
263     }
264 
265     @Test
startExplicitly_canStartVisible()266     public void startExplicitly_canStartVisible() throws Exception {
267         assertVisible(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS);
268         startExplicitIntentViaComponent(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS);
269         startExplicitIntentViaPackageName(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS);
270     }
271 
272     @Test
startImplicitly_canStartNonVisible()273     public void startImplicitly_canStartNonVisible() throws Exception {
274         assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS);
275         startImplicitIntent(QUERIES_NOTHING);
276     }
277 
278     @Test
startActivityWithNoPermissionUri_canSeeProvider()279     public void startActivityWithNoPermissionUri_canSeeProvider() throws Exception {
280         assertNotVisible(QUERIES_NOTHING_RECEIVES_URI, QUERIES_NOTHING_PERM);
281 
282         // send with uri but no grant flags; shouldn't be visible
283         startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_URI,
284                 new Intent(ACTION_JUST_FINISH)
285                         .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "/test")));
286         assertNotVisible(QUERIES_NOTHING_RECEIVES_URI, QUERIES_NOTHING_PERM);
287 
288         // send again with uri bug grant flags now set; should be visible
289         startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_URI,
290                 new Intent(ACTION_JUST_FINISH)
291                         .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "/test"))
292                         .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION));
293         assertVisible(QUERIES_NOTHING_RECEIVES_URI, QUERIES_NOTHING_PERM);
294     }
295 
296     @Test
startActivityWithUri_canSeePermissionProtectedProvider()297     public void startActivityWithUri_canSeePermissionProtectedProvider() throws Exception {
298         assertNotVisible(QUERIES_NOTHING_RECEIVES_PERM_URI, QUERIES_NOTHING_PERM);
299 
300         // send with uri but no grant flags; shouldn't be visible
301         startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_PERM_URI,
302                 new Intent(ACTION_JUST_FINISH)
303                         .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "2/test")));
304         assertNotVisible(QUERIES_NOTHING_RECEIVES_PERM_URI, QUERIES_NOTHING_PERM);
305 
306         // send again with uri bug grant flags now set; should be visible
307         startExplicitActivityWithIntent(QUERIES_NOTHING_PERM, QUERIES_NOTHING_RECEIVES_PERM_URI,
308                 new Intent(ACTION_JUST_FINISH)
309                         .setData(Uri.parse("content://" + QUERIES_NOTHING_PERM + "2/test"))
310                         .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION));
311         assertVisible(QUERIES_NOTHING_RECEIVES_PERM_URI, QUERIES_NOTHING_PERM);
312     }
313 
startExplicitActivityWithIntent( String sourcePackageName, String targetPackageName, Intent intent)314     private void startExplicitActivityWithIntent(
315             String sourcePackageName, String targetPackageName, Intent intent) throws Exception {
316         sendCommandBlocking(sourcePackageName, targetPackageName,
317                 intent.setClassName(targetPackageName, ACTIVITY_CLASS_TEST),
318                 ACTION_START_DIRECTLY);
319     }
320 
321     @Test
queriesNothing_cannotSeeNonForceQueryable()322     public void queriesNothing_cannotSeeNonForceQueryable() throws Exception {
323         assertNotVisible(QUERIES_NOTHING, TARGET_NO_API);
324         assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS);
325     }
326 
327     @Test
queriesNothingTargetsQ_canSeeAll()328     public void queriesNothingTargetsQ_canSeeAll() throws Exception {
329         assertVisible(QUERIES_NOTHING_Q, TARGET_FORCEQUERYABLE);
330         assertVisible(QUERIES_NOTHING_Q, TARGET_NO_API);
331         assertVisible(QUERIES_NOTHING_Q, TARGET_FILTERS);
332     }
333 
334     @Test
queriesNothingHasPermission_canSeeAll()335     public void queriesNothingHasPermission_canSeeAll() throws Exception {
336         assertVisible(QUERIES_NOTHING_PERM, TARGET_FORCEQUERYABLE);
337         assertVisible(QUERIES_NOTHING_PERM, TARGET_NO_API);
338         assertVisible(QUERIES_NOTHING_PERM, TARGET_FILTERS);
339     }
340 
341     @Test
queriesNothing_cannotSeeFilters()342     public void queriesNothing_cannotSeeFilters() throws Exception {
343         assertNotQueryable(QUERIES_NOTHING, TARGET_FILTERS,
344                 ACTION_MANIFEST_ACTIVITY, this::queryIntentActivities);
345         assertNotQueryable(QUERIES_NOTHING, TARGET_FILTERS,
346                 ACTION_MANIFEST_SERVICE, this::queryIntentServices);
347         assertNotQueryable(QUERIES_NOTHING, TARGET_FILTERS,
348                 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders);
349     }
350 
351     @Test
queriesActivityAction_canSeeFilters()352     public void queriesActivityAction_canSeeFilters() throws Exception {
353         assertQueryable(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS,
354                 ACTION_MANIFEST_ACTIVITY, this::queryIntentActivities);
355         assertQueryable(QUERIES_SERVICE_ACTION, TARGET_FILTERS,
356                 ACTION_MANIFEST_SERVICE, this::queryIntentServices);
357         assertQueryable(QUERIES_PROVIDER_AUTH, TARGET_FILTERS,
358                 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders);
359         assertQueryable(QUERIES_PROVIDER_ACTION, TARGET_FILTERS,
360                 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders);
361     }
362 
363     @Test
queriesNothingHasPermission_canSeeFilters()364     public void queriesNothingHasPermission_canSeeFilters() throws Exception {
365         assertQueryable(QUERIES_NOTHING_PERM, TARGET_FILTERS,
366                 ACTION_MANIFEST_ACTIVITY, this::queryIntentActivities);
367         assertQueryable(QUERIES_NOTHING_PERM, TARGET_FILTERS,
368                 ACTION_MANIFEST_SERVICE, this::queryIntentServices);
369         assertQueryable(QUERIES_NOTHING_PERM, TARGET_FILTERS,
370                 ACTION_MANIFEST_PROVIDER, this::queryIntentProviders);
371     }
372 
373     @Test
queriesSomething_cannotSeeNoApi()374     public void queriesSomething_cannotSeeNoApi() throws Exception {
375         assertNotVisible(QUERIES_ACTIVITY_ACTION, TARGET_NO_API);
376         assertNotVisible(QUERIES_SERVICE_ACTION, TARGET_NO_API);
377         assertNotVisible(QUERIES_PROVIDER_AUTH, TARGET_NO_API);
378         assertNotVisible(QUERIES_PROVIDER_ACTION, TARGET_NO_API);
379     }
380 
381     @Test
queriesActivityAction_canSeeTarget()382     public void queriesActivityAction_canSeeTarget() throws Exception {
383         assertVisible(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS);
384     }
385 
386     @Test
queriesServiceAction_canSeeTarget()387     public void queriesServiceAction_canSeeTarget() throws Exception {
388         assertVisible(QUERIES_SERVICE_ACTION, TARGET_FILTERS);
389     }
390 
391     @Test
queriesWildcardAction_canSeeTargets()392     public void queriesWildcardAction_canSeeTargets() throws Exception {
393         assertVisible(QUERIES_WILDCARD_ACTION, TARGET_FILTERS);
394     }
395 
396     @Test
queriesProviderAuthority_canSeeTarget()397     public void queriesProviderAuthority_canSeeTarget() throws Exception {
398         assertVisible(QUERIES_PROVIDER_AUTH, TARGET_FILTERS);
399     }
400 
401     @Test
queriesProviderAction_canSeeTarget()402     public void queriesProviderAction_canSeeTarget() throws Exception {
403         assertVisible(QUERIES_PROVIDER_ACTION, TARGET_FILTERS);
404     }
405 
406     @Test
queriesActivityAction_cannotSeeUnexportedTarget()407     public void queriesActivityAction_cannotSeeUnexportedTarget() throws Exception {
408         assertNotVisible(QUERIES_UNEXPORTED_ACTIVITY_ACTION, TARGET_FILTERS);
409     }
410 
411     @Test
queriesServiceAction_cannotSeeUnexportedTarget()412     public void queriesServiceAction_cannotSeeUnexportedTarget() throws Exception {
413         assertNotVisible(QUERIES_UNEXPORTED_SERVICE_ACTION, TARGET_FILTERS);
414     }
415 
416     @Test
queriesProviderAuthority_cannotSeeUnexportedTarget()417     public void queriesProviderAuthority_cannotSeeUnexportedTarget() throws Exception {
418         assertNotVisible(QUERIES_UNEXPORTED_PROVIDER_AUTH, TARGET_FILTERS);
419     }
420 
421     @Test
queriesProviderAction_cannotSeeUnexportedTarget()422     public void queriesProviderAction_cannotSeeUnexportedTarget() throws Exception {
423         assertNotVisible(QUERIES_UNEXPORTED_PROVIDER_ACTION, TARGET_FILTERS);
424     }
425 
426     @Test
queriesPackage_canSeeTarget()427     public void queriesPackage_canSeeTarget() throws Exception {
428         assertVisible(QUERIES_PACKAGE, TARGET_NO_API);
429     }
430 
431     @Test
queriesNothing_canSeeInstaller()432     public void queriesNothing_canSeeInstaller() throws Exception {
433         runShellCommand("pm uninstall " + QUERIES_NOTHING_SEES_INSTALLER);
434         runShellCommand("pm install"
435                 + " -i " + TARGET_NO_API
436                 + " --pkg " + QUERIES_NOTHING_SEES_INSTALLER
437                 + " " + QUERIES_NOTHING_SEES_INSTALLER_APK);
438         try {
439             assertVisible(QUERIES_NOTHING_SEES_INSTALLER, TARGET_NO_API);
440         } finally {
441             runShellCommand("pm uninstall " + QUERIES_NOTHING_SEES_INSTALLER);
442         }
443     }
444 
445 
446     @Test
whenStarted_canSeeCaller()447     public void whenStarted_canSeeCaller() throws Exception {
448         // let's first make sure that the target cannot see the caller.
449         assertNotVisible(QUERIES_NOTHING, QUERIES_NOTHING_PERM);
450         // now let's start the target and make sure that it can see the caller as part of that call
451         PackageInfo packageInfo = startForResult(QUERIES_NOTHING_PERM, QUERIES_NOTHING);
452         assertThat(packageInfo, IsNull.notNullValue());
453         assertThat(packageInfo.packageName, is(QUERIES_NOTHING_PERM));
454         // and finally let's re-run the last check to make sure that the target can still see the
455         // caller
456         assertVisible(QUERIES_NOTHING, QUERIES_NOTHING_PERM);
457     }
458 
459     @Test
whenStartedViaIntentSender_canSeeCaller()460     public void whenStartedViaIntentSender_canSeeCaller() throws Exception {
461         // let's first make sure that the target cannot see the caller.
462         assertNotVisible(QUERIES_NOTHING, QUERIES_NOTHING_Q);
463         // now let's start the target via pending intent and make sure that it can see the caller
464         // as part of that call
465         PackageInfo packageInfo = startSenderForResult(QUERIES_NOTHING_Q, QUERIES_NOTHING);
466         assertThat(packageInfo, IsNull.notNullValue());
467         assertThat(packageInfo.packageName, is(QUERIES_NOTHING_Q));
468         // and finally let's re-run the last check to make sure that the target can still see the
469         // caller
470         assertVisible(QUERIES_NOTHING, QUERIES_NOTHING_Q);
471     }
472 
473     @Test
queriesNothing_cannotSeeLibraryPackage()474     public void queriesNothing_cannotSeeLibraryPackage() throws Exception {
475         assertNotVisible(QUERIES_NOTHING, TARGET_SHARED_LIBRARY_PACKAGE);
476     }
477 
478     @Test
queriesNothingUsesLibrary_canSeeLibraryPackage()479     public void queriesNothingUsesLibrary_canSeeLibraryPackage() throws Exception {
480         assertVisible(QUERIES_NOTHING_USES_LIBRARY, TARGET_SHARED_LIBRARY_PACKAGE);
481     }
482 
483     @Test
queriesNothing_cannotSeeOptionalLibraryPackage()484     public void queriesNothing_cannotSeeOptionalLibraryPackage() throws Exception {
485         assertNotVisible(QUERIES_NOTHING, TARGET_SHARED_LIBRARY_PACKAGE);
486     }
487 
488     @Test
queriesNothingUsesOptionalLibrary_canSeeLibraryPackage()489     public void queriesNothingUsesOptionalLibrary_canSeeLibraryPackage() throws Exception {
490         assertVisible(QUERIES_NOTHING_USES_OPTIONAL_LIBRARY, TARGET_SHARED_LIBRARY_PACKAGE);
491     }
492 
493     @Test
queriesNothing_getPackagesForUid_consistentVisibility()494     public void queriesNothing_getPackagesForUid_consistentVisibility()
495             throws Exception {
496         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
497         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
498         Assert.assertNull(getPackagesForUid(QUERIES_NOTHING, targetSharedUid));
499         Assert.assertNull(getPackagesForUid(QUERIES_NOTHING, targetUid));
500     }
501 
502     @Test
queriesNothingHasPermission_getPackagesForUid_consistentVisibility()503     public void queriesNothingHasPermission_getPackagesForUid_consistentVisibility()
504             throws Exception {
505         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
506         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
507         Assert.assertNotNull(getPackagesForUid(QUERIES_NOTHING_PERM, targetSharedUid));
508         Assert.assertNotNull(getPackagesForUid(QUERIES_NOTHING_PERM, targetUid));
509     }
510 
511     @Test
queriesNothing_getNameForUid_consistentVisibility()512     public void queriesNothing_getNameForUid_consistentVisibility()
513             throws Exception {
514         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
515         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
516         Assert.assertNull(getNameForUid(QUERIES_NOTHING, targetSharedUid));
517         Assert.assertNull(getNameForUid(QUERIES_NOTHING, targetUid));
518     }
519 
520     @Test
queriesNothingHasPermission_getNameForUid_consistentVisibility()521     public void queriesNothingHasPermission_getNameForUid_consistentVisibility()
522             throws Exception {
523         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
524         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
525         Assert.assertNotNull(getNameForUid(QUERIES_NOTHING_PERM, targetSharedUid));
526         Assert.assertNotNull(getNameForUid(QUERIES_NOTHING_PERM, targetUid));
527     }
528 
529     @Test
queriesNothing_getNamesForUids_consistentVisibility()530     public void queriesNothing_getNamesForUids_consistentVisibility()
531             throws Exception {
532         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
533         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
534         Assert.assertNull(getNamesForUids(QUERIES_NOTHING, targetSharedUid)[0]);
535         Assert.assertNull(getNamesForUids(QUERIES_NOTHING, targetUid)[0]);
536     }
537 
538     @Test
queriesNothingHasPermission_getNamesForUids_consistentVisibility()539     public void queriesNothingHasPermission_getNamesForUids_consistentVisibility()
540             throws Exception {
541         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
542         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
543         Assert.assertNotNull(getNamesForUids(QUERIES_NOTHING_PERM, targetSharedUid)[0]);
544         Assert.assertNotNull(getNamesForUids(QUERIES_NOTHING_PERM, targetUid)[0]);
545     }
546 
547     @Test
queriesNothing_checkSignatures_consistentVisibility()548     public void queriesNothing_checkSignatures_consistentVisibility()
549             throws Exception {
550         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
551         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
552         Assert.assertEquals(SIGNATURE_UNKNOWN_PACKAGE,
553                 checkSignatures(QUERIES_NOTHING, targetSharedUid));
554         Assert.assertEquals(SIGNATURE_UNKNOWN_PACKAGE,
555                 checkSignatures(QUERIES_NOTHING, targetUid));
556     }
557 
558     @Test
queriesNothingHasPermission_checkSignatures_consistentVisibility()559     public void queriesNothingHasPermission_checkSignatures_consistentVisibility()
560             throws Exception {
561         final int targetSharedUid = sPm.getPackageUid(TARGET_SHARED_USER, /* flags */ 0);
562         final int targetUid = sPm.getPackageUid(TARGET_FILTERS, /* flags */ 0);
563         Assert.assertEquals(SIGNATURE_MATCH,
564                 checkSignatures(QUERIES_NOTHING_PERM, targetSharedUid));
565         Assert.assertEquals(SIGNATURE_MATCH, checkSignatures(QUERIES_NOTHING_PERM, targetUid));
566     }
567 
568     @Test
queriesNothing_hasSigningCertificate_consistentVisibility()569     public void queriesNothing_hasSigningCertificate_consistentVisibility() throws Exception {
570         final PackageInfo targetSharedUidInfo = sPm.getPackageInfo(TARGET_SHARED_USER,
571                 GET_SIGNING_CERTIFICATES);
572         final PackageInfo targetUidInfo = sPm.getPackageInfo(TARGET_FILTERS,
573                 GET_SIGNING_CERTIFICATES);
574         final byte[] targetSharedCert = convertSignaturesToCertificates(
575                 targetSharedUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded();
576         final byte[] targetCert = convertSignaturesToCertificates(
577                 targetUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded();
578 
579         Assert.assertFalse(
580                 hasSigningCertificate(QUERIES_NOTHING, targetSharedUidInfo.applicationInfo.uid,
581                         targetSharedCert));
582         Assert.assertFalse(
583                 hasSigningCertificate(QUERIES_NOTHING, targetUidInfo.applicationInfo.uid,
584                         targetCert));
585     }
586 
587     @Test
queriesNothingHasPermission_hasSigningCertificate_consistentVisibility()588     public void queriesNothingHasPermission_hasSigningCertificate_consistentVisibility()
589             throws Exception {
590         final PackageInfo targetSharedUidInfo = sPm.getPackageInfo(TARGET_SHARED_USER,
591                 GET_SIGNING_CERTIFICATES);
592         final PackageInfo targetUidInfo = sPm.getPackageInfo(TARGET_FILTERS,
593                 GET_SIGNING_CERTIFICATES);
594         final byte[] targetSharedCert = convertSignaturesToCertificates(
595                 targetSharedUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded();
596         final byte[] targetCert = convertSignaturesToCertificates(
597                 targetUidInfo.signingInfo.getApkContentsSigners()).get(0).getEncoded();
598 
599         Assert.assertTrue(
600                 hasSigningCertificate(QUERIES_NOTHING_PERM, targetSharedUidInfo.applicationInfo.uid,
601                         targetSharedCert));
602         Assert.assertTrue(
603                 hasSigningCertificate(QUERIES_NOTHING_PERM, targetUidInfo.applicationInfo.uid,
604                         targetCert));
605     }
606 
607     @Test
sharedUserMember_canSeeOtherMember()608     public void sharedUserMember_canSeeOtherMember() throws Exception {
609         assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SHARED_USER);
610     }
611 
612     @Test
queriesPackage_canSeeAllSharedUserMembers()613     public void queriesPackage_canSeeAllSharedUserMembers() throws Exception {
614         // explicitly queries target via manifest
615         assertVisible(QUERIES_PACKAGE, TARGET_SHARED_USER);
616         // implicitly granted visibility to other member of shared user
617         assertVisible(QUERIES_PACKAGE, QUERIES_NOTHING_SHARED_USER);
618     }
619 
620     @Test
queriesWildcardContacts()621     public void queriesWildcardContacts() throws Exception {
622         assertNotVisible(QUERIES_NOTHING, TARGET_CONTACTS);
623         assertVisible(QUERIES_WILDCARD_CONTACTS, TARGET_CONTACTS);
624     }
625 
626     @Test
queriesWildcardWeb()627     public void queriesWildcardWeb() throws Exception {
628         assertNotVisible(QUERIES_NOTHING, TARGET_WEB);
629         assertVisible(QUERIES_WILDCARD_BROWSABLE, TARGET_WEB);
630         assertVisible(QUERIES_WILDCARD_WEB, TARGET_WEB);
631     }
632 
633     @Test
queriesWildcardBrowser()634     public void queriesWildcardBrowser() throws Exception {
635         assertNotVisible(QUERIES_NOTHING, TARGET_BROWSER);
636         assertNotVisible(QUERIES_WILDCARD_BROWSER, TARGET_WEB);
637         assertVisible(QUERIES_WILDCARD_BROWSER, TARGET_BROWSER);
638         assertVisible(QUERIES_WILDCARD_BROWSER, TARGET_BROWSER_WILDCARD);
639     }
640 
641 
642     @Test
queriesWildcardEditor()643     public void queriesWildcardEditor() throws Exception {
644         assertNotVisible(QUERIES_NOTHING, TARGET_EDITOR);
645         assertVisible(QUERIES_WILDCARD_EDITOR, TARGET_EDITOR);
646     }
647 
648     @Test
queriesWildcardShareSheet()649     public void queriesWildcardShareSheet() throws Exception {
650         assertNotVisible(QUERIES_NOTHING, TARGET_SHARE);
651         assertVisible(QUERIES_WILDCARD_SHARE, TARGET_SHARE);
652     }
653 
654     @Test
queriesNothing_cannotSeeA11yService()655     public void queriesNothing_cannotSeeA11yService() throws Exception {
656         if (!sGlobalFeatureEnabled) return;
657         final String[] result = getInstalledAccessibilityServices(QUERIES_NOTHING);
658         assertThat(result, not(hasItemInArray(TARGET_FILTERS)));
659     }
660 
661     @Test
queriesNothingHasPermission_canSeeA11yService()662     public void queriesNothingHasPermission_canSeeA11yService() throws Exception {
663         if (!sGlobalFeatureEnabled) return;
664         final String[] result = getInstalledAccessibilityServices(QUERIES_NOTHING_PERM);
665         assertThat(QUERIES_NOTHING_PERM + " should be able to see " + TARGET_FILTERS,
666                 result, hasItemInArray(TARGET_FILTERS));
667     }
668 
assertVisible(String sourcePackageName, String targetPackageName)669     private void assertVisible(String sourcePackageName, String targetPackageName)
670             throws Exception {
671         if (!sGlobalFeatureEnabled) return;
672         Assert.assertNotNull(sourcePackageName + " should be able to see " + targetPackageName,
673                 getPackageInfo(sourcePackageName, targetPackageName));
674     }
675 
676     @Test
broadcastAdded_notVisibleDoesNotReceive()677     public void broadcastAdded_notVisibleDoesNotReceive() throws Exception {
678         final Result result = sendCommand(QUERIES_NOTHING, TARGET_FILTERS,
679                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
680                 Constants.ACTION_AWAIT_PACKAGE_ADDED, /* waitForReady */ true);
681         runShellCommand("pm install " + TARGET_FILTERS_APK);
682         try {
683             result.await();
684             fail();
685         } catch (MissingBroadcastException e) {
686             // hooray
687         }
688     }
689 
690     @Test
broadcastAdded_visibleReceives()691     public void broadcastAdded_visibleReceives() throws Exception {
692         final Result result = sendCommand(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS,
693                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
694                 Constants.ACTION_AWAIT_PACKAGE_ADDED, /* waitForReady */ true);
695         runShellCommand("pm install " + TARGET_FILTERS_APK);
696         try {
697             Assert.assertEquals(TARGET_FILTERS,
698                     Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart());
699         } catch (MissingBroadcastException e) {
700             fail();
701         }
702     }
703 
704     @Test
reinstallTarget_broadcastRemoved_notVisibleDoesNotReceive()705     public void reinstallTarget_broadcastRemoved_notVisibleDoesNotReceive() throws Exception {
706         final Result result = sendCommand(QUERIES_NOTHING, TARGET_FILTERS,
707                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
708                 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true);
709         runShellCommand("pm install " + TARGET_FILTERS_APK);
710         try {
711             result.await();
712             fail();
713         } catch (MissingBroadcastException e) {
714             // hooray
715         }
716     }
717 
718     @Test
reinstallTarget_broadcastRemoved_visibleReceives()719     public void reinstallTarget_broadcastRemoved_visibleReceives() throws Exception {
720         final Result result = sendCommand(QUERIES_ACTIVITY_ACTION, TARGET_FILTERS,
721                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
722                 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true);
723         runShellCommand("pm install " + TARGET_FILTERS_APK);
724         try {
725             Assert.assertEquals(TARGET_FILTERS,
726                     Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart());
727         } catch (MissingBroadcastException e) {
728             fail();
729         }
730     }
731 
732     @Test
uninstallTarget_broadcastRemoved_notVisibleDoesNotReceive()733     public void uninstallTarget_broadcastRemoved_notVisibleDoesNotReceive() throws Exception {
734         ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK);
735         final Result result = sendCommand(QUERIES_NOTHING, TARGET_STUB,
736                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
737                 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true);
738         runShellCommand("pm uninstall " + TARGET_STUB);
739         try {
740             result.await();
741             fail();
742         } catch (MissingBroadcastException e) {
743             // hooray
744         }
745     }
746 
747     @Test
uninstallTarget_broadcastRemoved_visibleReceives()748     public void uninstallTarget_broadcastRemoved_visibleReceives() throws Exception {
749         ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK);
750         final Result result = sendCommand(QUERIES_NOTHING_PERM, TARGET_STUB,
751                 /* targetUid */ INVALID_UID, /* intentExtra */ null,
752                 Constants.ACTION_AWAIT_PACKAGE_REMOVED, /* waitForReady */ true);
753         runShellCommand("pm uninstall " + TARGET_STUB);
754         try {
755             Assert.assertEquals(TARGET_STUB,
756                     Uri.parse(result.await().getString(EXTRA_DATA)).getSchemeSpecificPart());
757         } catch (MissingBroadcastException e) {
758             fail();
759         }
760     }
761 
762     @Test
broadcastSuspended_visibleReceives()763     public void broadcastSuspended_visibleReceives() throws Exception {
764         assertBroadcastSuspendedVisible(QUERIES_PACKAGE,
765                 Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER),
766                 Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER));
767     }
768 
769     @Test
broadcastSuspended_notVisibleDoesNotReceive()770     public void broadcastSuspended_notVisibleDoesNotReceive() throws Exception {
771         assertBroadcastSuspendedVisible(QUERIES_NOTHING,
772                 Arrays.asList(),
773                 Arrays.asList(TARGET_NO_API, TARGET_SYNCADAPTER));
774     }
775 
776     @Test
broadcastSuspended_visibleReceivesAndNotVisibleDoesNotReceive()777     public void broadcastSuspended_visibleReceivesAndNotVisibleDoesNotReceive() throws Exception {
778         assertBroadcastSuspendedVisible(QUERIES_ACTIVITY_ACTION,
779                 Arrays.asList(TARGET_FILTERS),
780                 Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
781     }
782 
783     @Test
launcherAppsCallback_added_notVisibleNotReceives()784     public void launcherAppsCallback_added_notVisibleNotReceives() throws Exception {
785         ensurePackageIsNotInstalled(TARGET_STUB);
786         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING,
787                 CALLBACK_EVENT_PACKAGE_ADDED);
788 
789         runShellCommand("pm install " + TARGET_STUB_APK);
790         final Bundle response = result.await();
791 
792         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID));
793         assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray());
794     }
795 
796     @Test
launcherAppsCallback_added_visibleReceives()797     public void launcherAppsCallback_added_visibleReceives() throws Exception {
798         ensurePackageIsNotInstalled(TARGET_STUB);
799         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING_PERM,
800                 CALLBACK_EVENT_PACKAGE_ADDED);
801 
802         runShellCommand("pm install " + TARGET_STUB_APK);
803         final Bundle response = result.await();
804 
805         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGE_ADDED));
806         assertThat(response.getStringArray(EXTRA_PACKAGES),
807                 arrayContainingInAnyOrder(new String[]{TARGET_STUB}));
808     }
809 
810     @Test
launcherAppsCallback_removed_notVisibleNotReceives()811     public void launcherAppsCallback_removed_notVisibleNotReceives() throws Exception {
812         ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK);
813         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING,
814                 CALLBACK_EVENT_PACKAGE_REMOVED);
815 
816         runShellCommand("pm uninstall " + TARGET_STUB);
817         final Bundle response = result.await();
818 
819         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID));
820         assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray());
821     }
822 
823     @Test
launcherAppsCallback_removed_visibleReceives()824     public void launcherAppsCallback_removed_visibleReceives() throws Exception {
825         ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK);
826         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING_PERM,
827                 CALLBACK_EVENT_PACKAGE_REMOVED);
828 
829         runShellCommand("pm uninstall " + TARGET_STUB);
830         final Bundle response = result.await();
831 
832         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGE_REMOVED));
833         assertThat(response.getStringArray(EXTRA_PACKAGES),
834                 arrayContainingInAnyOrder(new String[]{TARGET_STUB}));
835     }
836 
837     @Test
launcherAppsCallback_changed_notVisibleNotReceives()838     public void launcherAppsCallback_changed_notVisibleNotReceives() throws Exception {
839         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING,
840                 CALLBACK_EVENT_PACKAGE_CHANGED);
841 
842         runShellCommand("pm install " + TARGET_FILTERS_APK);
843         final Bundle response = result.await();
844 
845         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID));
846         assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray());
847     }
848 
849     @Test
launcherAppsCallback_changed_visibleReceives()850     public void launcherAppsCallback_changed_visibleReceives() throws Exception {
851         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING_PERM,
852                 CALLBACK_EVENT_PACKAGE_CHANGED);
853 
854         runShellCommand("pm install " + TARGET_FILTERS_APK);
855         final Bundle response = result.await();
856 
857         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGE_CHANGED));
858         assertThat(response.getStringArray(EXTRA_PACKAGES),
859                 arrayContainingInAnyOrder(new String[]{TARGET_FILTERS}));
860     }
861 
862     @Test
launcherAppsCallback_suspended_notVisibleNotReceives()863     public void launcherAppsCallback_suspended_notVisibleNotReceives() throws Exception {
864         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING,
865                 CALLBACK_EVENT_PACKAGES_SUSPENDED);
866 
867         try {
868             setPackagesSuspended(/* suspend */ true,
869                     Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
870             final Bundle response = result.await();
871 
872             assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID));
873             assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray());
874         } finally {
875             setPackagesSuspended(/* suspend */ false,
876                     Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
877         }
878     }
879 
880     @Test
launcherAppsCallback_suspended_visibleReceives()881     public void launcherAppsCallback_suspended_visibleReceives() throws Exception {
882         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_ACTIVITY_ACTION,
883                 CALLBACK_EVENT_PACKAGES_SUSPENDED);
884 
885         try {
886             setPackagesSuspended(/* suspend */ true,
887                     Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
888             final Bundle response = result.await();
889 
890             assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGES_SUSPENDED));
891             assertThat(response.getStringArray(EXTRA_PACKAGES),
892                     arrayContainingInAnyOrder(new String[]{TARGET_FILTERS}));
893         } finally {
894             setPackagesSuspended(/* suspend */ false,
895                     Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
896         }
897     }
898 
899     @Test
launcherAppsCallback_unsuspended_notVisibleNotReceives()900     public void launcherAppsCallback_unsuspended_notVisibleNotReceives() throws Exception {
901         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_NOTHING,
902                 CALLBACK_EVENT_PACKAGES_UNSUSPENDED);
903 
904         setPackagesSuspended(/* suspend */ false, Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
905         final Bundle response = result.await();
906 
907         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_INVALID));
908         assertThat(response.getStringArray(EXTRA_PACKAGES), emptyArray());
909     }
910 
911     @Test
launcherAppsCallback_unsuspended_visibleReceives()912     public void launcherAppsCallback_unsuspended_visibleReceives() throws Exception {
913         final Result result = sendCommandAndWaitForLauncherAppsCallback(QUERIES_ACTIVITY_ACTION,
914                 CALLBACK_EVENT_PACKAGES_UNSUSPENDED);
915 
916         setPackagesSuspended(/* suspend */ false, Arrays.asList(TARGET_NO_API, TARGET_FILTERS));
917         final Bundle response = result.await();
918 
919         assertThat(response.getInt(EXTRA_FLAGS), equalTo(CALLBACK_EVENT_PACKAGES_UNSUSPENDED));
920         assertThat(response.getStringArray(EXTRA_PACKAGES),
921                 arrayContainingInAnyOrder(new String[]{TARGET_FILTERS}));
922     }
923 
924     @Test
queriesResolver_grantsVisibilityToProvider()925     public void queriesResolver_grantsVisibilityToProvider() throws Exception {
926         assertNotVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM);
927 
928         String[] result = sendCommandBlocking(
929                 QUERIES_NOTHING_PERM, QUERIES_NOTHING_PROVIDER, null, ACTION_QUERY_RESOLVER)
930                 .getStringArray(Intent.EXTRA_RETURN_RESULT);
931         Arrays.sort(result);
932         assertThat(QUERIES_NOTHING_PERM + " not visible to " + QUERIES_NOTHING_PROVIDER
933                         + " during resolver interaction",
934                 Arrays.binarySearch(result, QUERIES_NOTHING_PERM),
935                 greaterThanOrEqualTo(0));
936 
937         assertVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM);
938     }
939 
940     @Test
bindService_consistentVisibility()941     public void bindService_consistentVisibility() throws Exception {
942         // Ensure package visibility isn't impacted by optimization or cached result.
943         // Target service shouldn't be visible to app without query permission even if
944         // another app with query permission is binding it.
945         assertServiceVisible(QUERIES_NOTHING_PERM, TARGET_FILTERS);
946         assertServiceNotVisible(QUERIES_NOTHING, TARGET_FILTERS);
947     }
948 
949     @Test
queriesPackage_getSyncAdapterTypes_canSeeSyncadapterTarget()950     public void queriesPackage_getSyncAdapterTypes_canSeeSyncadapterTarget() throws Exception {
951         assertVisible(QUERIES_PACKAGE, TARGET_SYNCADAPTER, this::getSyncAdapterTypes);
952     }
953 
954     @Test
queriesNothing_getSyncAdapterTypes_cannotSeeSyncadapterTarget()955     public void queriesNothing_getSyncAdapterTypes_cannotSeeSyncadapterTarget() throws Exception {
956         assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER, this::getSyncAdapterTypes);
957         assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER_SHARED_USER,
958                 this::getSyncAdapterTypes);
959     }
960 
961     @Test
queriesNothingSharedUser_getSyncAdapterTypes_canSeeSyncadapterSharedUserTarget()962     public void queriesNothingSharedUser_getSyncAdapterTypes_canSeeSyncadapterSharedUserTarget()
963             throws Exception {
964         assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SYNCADAPTER_SHARED_USER,
965                 this::getSyncAdapterTypes);
966     }
967 
968     @Test
queriesPackage_getSyncAdapterPackages_canSeeSyncadapterTarget()969     public void queriesPackage_getSyncAdapterPackages_canSeeSyncadapterTarget()
970             throws Exception {
971         assertVisible(QUERIES_PACKAGE, TARGET_SYNCADAPTER,
972                 this::getSyncAdapterPackagesForAuthorityAsUser);
973     }
974 
975     @Test
queriesNothing_getSyncAdapterPackages_cannotSeeSyncadapterTarget()976     public void queriesNothing_getSyncAdapterPackages_cannotSeeSyncadapterTarget()
977             throws Exception {
978         assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER,
979                 this::getSyncAdapterPackagesForAuthorityAsUser);
980         assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER_SHARED_USER,
981                 this::getSyncAdapterPackagesForAuthorityAsUser);
982     }
983 
984     @Test
queriesNothingSharedUser_getSyncAdapterPackages_canSeeSyncadapterSharedUserTarget()985     public void queriesNothingSharedUser_getSyncAdapterPackages_canSeeSyncadapterSharedUserTarget()
986             throws Exception {
987         assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SYNCADAPTER_SHARED_USER,
988                 this::getSyncAdapterPackagesForAuthorityAsUser);
989     }
990 
991     @Test
launcherAppsIsActivityEnabled_queriesActivityAction_canSeeActivity()992     public void launcherAppsIsActivityEnabled_queriesActivityAction_canSeeActivity()
993             throws Exception {
994         final ComponentName targetFilters = ComponentName.createRelative(TARGET_FILTERS,
995                 ACTIVITY_CLASS_DUMMY_ACTIVITY);
996         assertThat(QUERIES_ACTIVITY_ACTION + " should be able to see " + targetFilters,
997                 launcherAppsIsActivityEnabled(QUERIES_ACTIVITY_ACTION, targetFilters),
998                 is(true));
999     }
1000 
1001     @Test
launcherAppsIsActivityEnabled_queriesNothing_cannotSeeActivity()1002     public void launcherAppsIsActivityEnabled_queriesNothing_cannotSeeActivity()
1003             throws Exception {
1004         final ComponentName targetFilters = ComponentName.createRelative(TARGET_FILTERS,
1005                 ACTIVITY_CLASS_DUMMY_ACTIVITY);
1006         assertThat(QUERIES_ACTIVITY_ACTION + " should not be able to see " + targetFilters,
1007                 launcherAppsIsActivityEnabled(QUERIES_NOTHING, targetFilters),
1008                 is(false));
1009     }
1010 
1011     @Test
queriesPackage_canSeeAppWidgetProviderTarget()1012     public void queriesPackage_canSeeAppWidgetProviderTarget() throws Exception {
1013         assertVisible(QUERIES_PACKAGE, TARGET_APPWIDGETPROVIDER,
1014                 this::getInstalledAppWidgetProviders);
1015     }
1016 
1017     @Test
queriesNothing_cannotSeeAppWidgetProviderTarget()1018     public void queriesNothing_cannotSeeAppWidgetProviderTarget() throws Exception {
1019         assertNotVisible(QUERIES_NOTHING, TARGET_APPWIDGETPROVIDER,
1020                 this::getInstalledAppWidgetProviders);
1021         assertNotVisible(QUERIES_NOTHING, TARGET_APPWIDGETPROVIDER_SHARED_USER,
1022                 this::getInstalledAppWidgetProviders);
1023     }
1024 
1025     @Test
queriesNothingSharedUser_canSeeAppWidgetProviderSharedUserTarget()1026     public void queriesNothingSharedUser_canSeeAppWidgetProviderSharedUserTarget()
1027             throws Exception {
1028         assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_APPWIDGETPROVIDER_SHARED_USER,
1029                 this::getInstalledAppWidgetProviders);
1030     }
1031 
1032     @Test
queriesNothing_cannotSeeSharedLibraryDependentPackages()1033     public void queriesNothing_cannotSeeSharedLibraryDependentPackages() throws Exception {
1034         assertNotVisible(QUERIES_NOTHING, TARGET_NO_API, this::getSharedLibraryDependentPackages);
1035         assertNotVisible(QUERIES_NOTHING, TARGET_FILTERS, this::getSharedLibraryDependentPackages);
1036         assertNotVisible(QUERIES_NOTHING, TARGET_SHARED_USER,
1037                 this::getSharedLibraryDependentPackages);
1038 
1039     }
1040 
1041     @Test
queriesPackage_canSeeSharedLibraryDependentPackages()1042     public void queriesPackage_canSeeSharedLibraryDependentPackages() throws Exception {
1043         assertVisible(QUERIES_PACKAGE, TARGET_NO_API, this::getSharedLibraryDependentPackages);
1044         assertVisible(QUERIES_PACKAGE, TARGET_SHARED_USER, this::getSharedLibraryDependentPackages);
1045     }
1046 
1047     @Test
queriesNothingSharedUser_canSeeSharedUserInSharedLibraryDependentPackages()1048     public void queriesNothingSharedUser_canSeeSharedUserInSharedLibraryDependentPackages()
1049             throws Exception {
1050         assertVisible(QUERIES_NOTHING_SHARED_USER, TARGET_SHARED_USER,
1051                 this::getSharedLibraryDependentPackages);
1052     }
1053 
1054     @Test
queriesNothing_cannotSeePreferredActivityTarget()1055     public void queriesNothing_cannotSeePreferredActivityTarget() throws Exception {
1056         addPreferredActivity();
1057         try {
1058             assertNotVisible(QUERIES_NOTHING, TARGET_PREFERRED_ACTIVITY,
1059                     this::getPreferredActivities);
1060         } finally {
1061             clearPreferredActivity();
1062         }
1063     }
1064 
1065     @Test
queriesPackage_canSeePreferredActivityTarget()1066     public void queriesPackage_canSeePreferredActivityTarget() throws Exception {
1067         addPreferredActivity();
1068         try {
1069             assertVisible(QUERIES_PACKAGE, TARGET_PREFERRED_ACTIVITY,
1070                     this::getPreferredActivities);
1071         } finally {
1072             clearPreferredActivity();
1073         }
1074     }
1075 
1076     @Test
queriesNothing_setInstallerPackageName_targetIsNoApi_throwsException()1077     public void queriesNothing_setInstallerPackageName_targetIsNoApi_throwsException() {
1078         final Exception ex = assertThrows(IllegalArgumentException.class,
1079                 () -> setInstallerPackageName(QUERIES_NOTHING, TARGET_NO_API, QUERIES_NOTHING));
1080         assertThat(ex.getMessage(), containsString(TARGET_NO_API));
1081     }
1082 
1083     @Test
queriesNothing_setInstallerPackageName_installerIsNoApi_throwsException()1084     public void queriesNothing_setInstallerPackageName_installerIsNoApi_throwsException() {
1085         final Exception ex = assertThrows(IllegalArgumentException.class,
1086                 () -> setInstallerPackageName(QUERIES_NOTHING, QUERIES_NOTHING, TARGET_NO_API));
1087         assertThat(ex.getMessage(), containsString(TARGET_NO_API));
1088     }
1089 
assertNotVisible(String sourcePackageName, String targetPackageName)1090     private void assertNotVisible(String sourcePackageName, String targetPackageName)
1091             throws Exception {
1092         if (!sGlobalFeatureEnabled) return;
1093         try {
1094             getPackageInfo(sourcePackageName, targetPackageName);
1095             fail(sourcePackageName + " should not be able to see " + targetPackageName);
1096         } catch (PackageManager.NameNotFoundException ignored) {
1097         }
1098     }
1099 
assertServiceVisible(String sourcePackageName, String targetPackageName)1100     private void assertServiceVisible(String sourcePackageName, String targetPackageName)
1101             throws Exception {
1102         if (!sGlobalFeatureEnabled) return;
1103         assertTrue(bindService(sourcePackageName, targetPackageName));
1104     }
1105 
assertServiceNotVisible(String sourcePackageName, String targetPackageName)1106     private void assertServiceNotVisible(String sourcePackageName, String targetPackageName)
1107             throws Exception {
1108         if (!sGlobalFeatureEnabled) return;
1109         assertFalse(bindService(sourcePackageName, targetPackageName));
1110     }
1111 
1112     interface ThrowingBiFunction<T, U, R> {
apply(T arg1, U arg2)1113         R apply(T arg1, U arg2) throws Exception;
1114     }
1115 
1116     interface ThrowingFunction<T, R> {
apply(T arg1)1117         R apply(T arg1) throws Exception;
1118     }
1119 
assertNotQueryable(String sourcePackageName, String targetPackageName, String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)1120     private void assertNotQueryable(String sourcePackageName, String targetPackageName,
1121             String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)
1122             throws Exception {
1123         if (!sGlobalFeatureEnabled) return;
1124         Intent intent = new Intent(intentAction);
1125         String[] queryablePackageNames = commandMethod.apply(sourcePackageName, intent);
1126         for (String packageName : queryablePackageNames) {
1127             if (packageName.contentEquals(targetPackageName)) {
1128                 fail(sourcePackageName + " should not be able to query " + targetPackageName +
1129                         " via " + intentAction);
1130             }
1131         }
1132     }
1133 
assertQueryable(String sourcePackageName, String targetPackageName, String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)1134     private void assertQueryable(String sourcePackageName, String targetPackageName,
1135             String intentAction, ThrowingBiFunction<String, Intent, String[]> commandMethod)
1136             throws Exception {
1137         if (!sGlobalFeatureEnabled) return;
1138         Intent intent = new Intent(intentAction);
1139         String[] queryablePackageNames = commandMethod.apply(sourcePackageName, intent);
1140         for (String packageName : queryablePackageNames) {
1141             if (packageName.contentEquals(targetPackageName)) {
1142                 return;
1143             }
1144         }
1145         fail(sourcePackageName + " should be able to query " + targetPackageName + " via "
1146                 + intentAction);
1147     }
1148 
assertVisible(String sourcePackageName, String targetPackageName, ThrowingFunction<String, String[]> commandMethod)1149     private void assertVisible(String sourcePackageName, String targetPackageName,
1150             ThrowingFunction<String, String[]> commandMethod) throws Exception {
1151         if (!sGlobalFeatureEnabled) return;
1152         final String[] packageNames = commandMethod.apply(sourcePackageName);
1153         assertThat("The list of package names should not be null",
1154                 packageNames, notNullValue());
1155         assertThat(sourcePackageName + " should be able to see " + targetPackageName,
1156                 packageNames, hasItemInArray(targetPackageName));
1157     }
1158 
assertNotVisible(String sourcePackageName, String targetPackageName, ThrowingFunction<String, String[]> commandMethod)1159     private void assertNotVisible(String sourcePackageName, String targetPackageName,
1160             ThrowingFunction<String, String[]> commandMethod) throws Exception {
1161         if (!sGlobalFeatureEnabled) return;
1162         final String[] packageNames = commandMethod.apply(sourcePackageName);
1163         assertThat("The list of package names should not be null",
1164                 packageNames, notNullValue());
1165         assertThat(sourcePackageName + " should not be able to see " + targetPackageName,
1166                 packageNames, not(hasItemInArray(targetPackageName)));
1167     }
1168 
assertVisible(String sourcePackageName, String targetPackageName, ThrowingBiFunction<String, String, String[]> commandMethod)1169     private void assertVisible(String sourcePackageName, String targetPackageName,
1170             ThrowingBiFunction<String, String, String[]> commandMethod) throws Exception {
1171         if (!sGlobalFeatureEnabled) return;
1172         final String[] packageNames = commandMethod.apply(sourcePackageName, targetPackageName);
1173         assertThat(sourcePackageName + " should be able to see " + targetPackageName,
1174                 packageNames, hasItemInArray(targetPackageName));
1175     }
1176 
assertNotVisible(String sourcePackageName, String targetPackageName, ThrowingBiFunction<String, String, String[]> commandMethod)1177     private void assertNotVisible(String sourcePackageName, String targetPackageName,
1178             ThrowingBiFunction<String, String, String[]> commandMethod) throws Exception {
1179         if (!sGlobalFeatureEnabled) return;
1180         final String[] packageNames = commandMethod.apply(sourcePackageName, targetPackageName);
1181         assertThat(sourcePackageName + " should not be able to see " + targetPackageName,
1182                 packageNames, not(hasItemInArray(targetPackageName)));
1183     }
1184 
assertBroadcastSuspendedVisible(String sourcePackageName, List<String> expectedVisiblePackages, List<String> packagesToSuspend)1185     private void assertBroadcastSuspendedVisible(String sourcePackageName,
1186             List<String> expectedVisiblePackages, List<String> packagesToSuspend)
1187             throws Exception {
1188         final Bundle extras = new Bundle();
1189         extras.putStringArray(EXTRA_PACKAGES, packagesToSuspend.toArray(new String[] {}));
1190         final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null,
1191                 /* targetUid */ INVALID_UID, extras, Constants.ACTION_AWAIT_PACKAGES_SUSPENDED,
1192                 /* waitForReady */ true);
1193         try {
1194             setPackagesSuspended(true, packagesToSuspend);
1195             final String[] suspendedPackages = result.await().getStringArray(EXTRA_PACKAGES);
1196             assertThat(suspendedPackages, arrayContainingInAnyOrder(
1197                     expectedVisiblePackages.toArray()));
1198         } finally {
1199             setPackagesSuspended(false, packagesToSuspend);
1200         }
1201     }
1202 
getInstalledAccessibilityServices(String sourcePackageName)1203     private String[] getInstalledAccessibilityServices (String sourcePackageName)
1204             throws Exception {
1205         final Bundle response = sendCommandBlocking(sourcePackageName, null /*targetPackageName*/,
1206                 null /*queryIntent*/, ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES);
1207         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1208     }
1209 
getPackageInfo(String sourcePackageName, String targetPackageName)1210     private PackageInfo getPackageInfo(String sourcePackageName, String targetPackageName)
1211             throws Exception {
1212         Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName,
1213                 null /*queryIntent*/, ACTION_GET_PACKAGE_INFO);
1214         return response.getParcelable(Intent.EXTRA_RETURN_RESULT);
1215     }
1216 
getPackagesForUid(String sourcePackageName, int targetUid)1217     private String[] getPackagesForUid(String sourcePackageName, int targetUid)
1218             throws Exception {
1219         final Bundle response = sendCommandBlocking(sourcePackageName, targetUid,
1220                 /* intentExtra */ null, ACTION_GET_PACKAGES_FOR_UID);
1221         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1222     }
1223 
getNameForUid(String sourcePackageName, int targetUid)1224     private String getNameForUid(String sourcePackageName, int targetUid) throws Exception {
1225         final Bundle response = sendCommandBlocking(sourcePackageName, targetUid,
1226                 /* intentExtra */ null, ACTION_GET_NAME_FOR_UID);
1227         return response.getString(Intent.EXTRA_RETURN_RESULT);
1228     }
1229 
getNamesForUids(String sourcePackageName, int targetUid)1230     private String[] getNamesForUids(String sourcePackageName, int targetUid) throws Exception {
1231         final Bundle response = sendCommandBlocking(sourcePackageName, targetUid,
1232                 /* intentExtra */ null, ACTION_GET_NAMES_FOR_UIDS);
1233         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1234     }
1235 
checkSignatures(String sourcePackageName, int targetUid)1236     private int checkSignatures(String sourcePackageName, int targetUid) throws Exception {
1237         final Bundle response = sendCommandBlocking(sourcePackageName, targetUid,
1238                 /* intentExtra */ null, ACTION_CHECK_SIGNATURES);
1239         return response.getInt(Intent.EXTRA_RETURN_RESULT);
1240     }
1241 
hasSigningCertificate(String sourcePackageName, int targetUid, byte[] cert)1242     private boolean hasSigningCertificate(String sourcePackageName, int targetUid, byte[] cert)
1243             throws Exception {
1244         final Bundle extra = new Bundle();
1245         extra.putByteArray(EXTRA_CERT, cert);
1246         final Bundle response = sendCommandBlocking(sourcePackageName, targetUid, extra,
1247                 ACTION_HAS_SIGNING_CERTIFICATE);
1248         return response.getBoolean(Intent.EXTRA_RETURN_RESULT);
1249     }
1250 
convertSignaturesToCertificates(Signature[] signatures)1251     private List<Certificate> convertSignaturesToCertificates(Signature[] signatures)
1252             throws Exception {
1253         final CertificateFactory cf = CertificateFactory.getInstance("X.509");
1254         ArrayList<Certificate> certs = new ArrayList<>(signatures.length);
1255         for (Signature signature : signatures) {
1256             final InputStream is = new ByteArrayInputStream(signature.toByteArray());
1257             final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
1258             certs.add(cert);
1259         }
1260         return certs;
1261     }
1262 
startForResult(String sourcePackageName, String targetPackageName)1263     private PackageInfo startForResult(String sourcePackageName, String targetPackageName)
1264             throws Exception {
1265         Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName,
1266                 null /*queryIntent*/, ACTION_START_FOR_RESULT);
1267         return response.getParcelable(Intent.EXTRA_RETURN_RESULT);
1268     }
1269 
startSenderForResult(String sourcePackageName, String targetPackageName)1270     private PackageInfo startSenderForResult(String sourcePackageName, String targetPackageName)
1271             throws Exception {
1272         PendingIntent pendingIntent = PendingIntent.getActivity(
1273                 InstrumentationRegistry.getInstrumentation().getContext(), 100,
1274                 new Intent("android.appenumeration.cts.action.SEND_RESULT").setComponent(
1275                         new ComponentName(targetPackageName,
1276                                 "android.appenumeration.cts.query.TestActivity")),
1277                 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
1278 
1279         Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName,
1280                 pendingIntent /*queryIntent*/, Constants.ACTION_START_SENDER_FOR_RESULT);
1281         return response.getParcelable(Intent.EXTRA_RETURN_RESULT);
1282     }
1283 
1284 
queryIntentActivities(String sourcePackageName, Intent queryIntent)1285     private String[] queryIntentActivities(String sourcePackageName, Intent queryIntent)
1286             throws Exception {
1287         Bundle response =
1288                 sendCommandBlocking(sourcePackageName, null, queryIntent, ACTION_QUERY_ACTIVITIES);
1289         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1290     }
1291 
queryIntentServices(String sourcePackageName, Intent queryIntent)1292     private String[] queryIntentServices(String sourcePackageName, Intent queryIntent)
1293             throws Exception {
1294         Bundle response = sendCommandBlocking(sourcePackageName, null, queryIntent,
1295                 ACTION_QUERY_SERVICES);
1296         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1297     }
1298 
queryIntentProviders(String sourcePackageName, Intent queryIntent)1299     private String[] queryIntentProviders(String sourcePackageName, Intent queryIntent)
1300             throws Exception {
1301         Bundle response = sendCommandBlocking(sourcePackageName, null, queryIntent,
1302                 ACTION_QUERY_PROVIDERS);
1303         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1304     }
1305 
getInstalledPackages(String sourcePackageNames, int flags)1306     private String[] getInstalledPackages(String sourcePackageNames, int flags) throws Exception {
1307         Bundle response = sendCommandBlocking(sourcePackageNames, null,
1308                 new Intent().putExtra(EXTRA_FLAGS, flags), ACTION_GET_INSTALLED_PACKAGES);
1309         return response.getStringArray(Intent.EXTRA_RETURN_RESULT);
1310     }
1311 
startExplicitIntentViaComponent(String sourcePackage, String targetPackage)1312     private void startExplicitIntentViaComponent(String sourcePackage, String targetPackage)
1313             throws Exception {
1314         sendCommandBlocking(sourcePackage, targetPackage,
1315                 new Intent().setComponent(new ComponentName(targetPackage,
1316                         ACTIVITY_CLASS_DUMMY_ACTIVITY)),
1317                 ACTION_START_DIRECTLY);
1318     }
startExplicitIntentViaPackageName(String sourcePackage, String targetPackage)1319     private void startExplicitIntentViaPackageName(String sourcePackage, String targetPackage)
1320             throws Exception {
1321         sendCommandBlocking(sourcePackage, targetPackage,
1322                 new Intent().setPackage(targetPackage),
1323                 ACTION_START_DIRECTLY);
1324     }
1325 
startImplicitIntent(String sourcePackage)1326     private void startImplicitIntent(String sourcePackage) throws Exception {
1327         sendCommandBlocking(sourcePackage, TARGET_FILTERS, new Intent(ACTION_MANIFEST_ACTIVITY),
1328                 ACTION_START_DIRECTLY);
1329     }
1330 
bindService(String sourcePackageName, String targetPackageName)1331     private boolean bindService(String sourcePackageName, String targetPackageName)
1332             throws Exception {
1333         final Bundle response = sendCommandBlocking(sourcePackageName, targetPackageName,
1334                 /* intentExtra */ null, ACTION_BIND_SERVICE);
1335         return response.getBoolean(Intent.EXTRA_RETURN_RESULT);
1336     }
1337 
getSyncAdapterTypes(String sourcePackageName)1338     private String[] getSyncAdapterTypes(String sourcePackageName) throws Exception {
1339         final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null,
1340                 /* intentExtra */ null, ACTION_GET_SYNCADAPTER_TYPES);
1341         final List<Parcelable> parcelables = response.getParcelableArrayList(
1342                 Intent.EXTRA_RETURN_RESULT);
1343         return parcelables.stream()
1344                 .map(parcelable -> ((SyncAdapterType) parcelable).getPackageName())
1345                 .distinct()
1346                 .toArray(String[]::new);
1347     }
1348 
getInstalledAppWidgetProviders(String sourcePackageName)1349     private String[] getInstalledAppWidgetProviders(String sourcePackageName) throws Exception {
1350         final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null,
1351                 /* intentExtra */ null, ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS);
1352         final List<Parcelable> parcelables = response.getParcelableArrayList(
1353                 Intent.EXTRA_RETURN_RESULT);
1354         return parcelables.stream()
1355                 .map(parcelable -> ((AppWidgetProviderInfo) parcelable).provider.getPackageName())
1356                 .distinct()
1357                 .toArray(String[]::new);
1358     }
1359 
getSyncAdapterPackagesForAuthorityAsUser(String sourcePackageName, String targetPackageName)1360     private String[] getSyncAdapterPackagesForAuthorityAsUser(String sourcePackageName,
1361             String targetPackageName) throws Exception {
1362         final Bundle extraData = new Bundle();
1363         extraData.putString(EXTRA_AUTHORITY, targetPackageName + ".authority");
1364         extraData.putInt(Intent.EXTRA_USER, Process.myUserHandle().getIdentifier());
1365         final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null,
1366                 extraData, ACTION_GET_SYNCADAPTER_PACKAGES_FOR_AUTHORITY);
1367         return response.getStringArray(Intent.EXTRA_PACKAGES);
1368     }
1369 
setPackagesSuspended(boolean suspend, List<String> packages)1370     private void setPackagesSuspended(boolean suspend, List<String> packages) {
1371         final StringBuilder cmd = new StringBuilder("pm ");
1372         if (suspend) {
1373             cmd.append("suspend");
1374         } else {
1375             cmd.append("unsuspend");
1376         }
1377         cmd.append(" --user cur");
1378         packages.stream().forEach(p -> cmd.append(" ").append(p));
1379         runShellCommand(cmd.toString());
1380     }
1381 
launcherAppsIsActivityEnabled(String sourcePackageName, ComponentName componentName)1382     private boolean launcherAppsIsActivityEnabled(String sourcePackageName,
1383             ComponentName componentName) throws Exception {
1384         final Bundle extraData = new Bundle();
1385         extraData.putString(Intent.EXTRA_COMPONENT_NAME, componentName.flattenToString());
1386         final Bundle response = sendCommandBlocking(sourcePackageName, /* targetPackageName */ null,
1387                 extraData, ACTION_LAUNCHER_APPS_IS_ACTIVITY_ENABLED);
1388         return response.getBoolean(Intent.EXTRA_RETURN_RESULT);
1389     }
1390 
getSharedLibraryDependentPackages(String sourcePackageName)1391     private String[] getSharedLibraryDependentPackages(String sourcePackageName) throws Exception {
1392         final Bundle extraData = new Bundle();
1393         final Bundle response = sendCommandBlocking(sourcePackageName, TEST_SHARED_LIB_NAME,
1394                 extraData, ACTION_GET_SHAREDLIBRARY_DEPENDENT_PACKAGES);
1395         return response.getStringArray(Intent.EXTRA_PACKAGES);
1396     }
1397 
getPreferredActivities(String sourcePackageName)1398     private String[] getPreferredActivities(String sourcePackageName) throws Exception {
1399         final Bundle extraData = new Bundle();
1400         final Bundle response = sendCommandBlocking(sourcePackageName, null /* targetPackageName */,
1401                 extraData, ACTION_GET_PREFERRED_ACTIVITIES);
1402         return response.getStringArray(Intent.EXTRA_PACKAGES);
1403     }
1404 
setInstallerPackageName(String sourcePackageName, String targetPackageName, String installerPackageName)1405     private void setInstallerPackageName(String sourcePackageName, String targetPackageName,
1406             String installerPackageName) throws Exception {
1407         final Bundle extraData = new Bundle();
1408         extraData.putString(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
1409         sendCommandBlocking(sourcePackageName, targetPackageName,
1410                 extraData, ACTION_SET_INSTALLER_PACKAGE_NAME);
1411     }
1412 
1413     interface Result {
await()1414         Bundle await() throws Exception;
1415     }
1416 
sendCommand(String sourcePackageName, @Nullable String targetPackageName, int targetUid, @Nullable Parcelable intentExtra, String action, boolean waitForReady)1417     private Result sendCommand(String sourcePackageName, @Nullable String targetPackageName,
1418             int targetUid, @Nullable Parcelable intentExtra, String action, boolean waitForReady)
1419             throws Exception {
1420         final Intent intent = new Intent(action)
1421                 .setComponent(new ComponentName(sourcePackageName, ACTIVITY_CLASS_TEST))
1422                 // data uri unique to each activity start to ensure actual launch and not just
1423                 // redisplay
1424                 .setData(Uri.parse("test://" + UUID.randomUUID().toString()))
1425                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
1426         if (targetPackageName != null) {
1427             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
1428         }
1429         if (targetUid > INVALID_UID) {
1430             intent.putExtra(Intent.EXTRA_UID, targetUid);
1431         }
1432         if (intentExtra != null) {
1433             if (intentExtra instanceof Intent) {
1434                 intent.putExtra(Intent.EXTRA_INTENT, intentExtra);
1435             } else if (intentExtra instanceof PendingIntent) {
1436                 intent.putExtra("pendingIntent", intentExtra);
1437             } else if (intentExtra instanceof Bundle) {
1438                 intent.putExtra(EXTRA_DATA, intentExtra);
1439             }
1440         }
1441 
1442         final ConditionVariable latch = new ConditionVariable();
1443         final AtomicReference<Bundle> resultReference = new AtomicReference<>();
1444         final RemoteCallback callback = new RemoteCallback(
1445                 bundle -> {
1446                     resultReference.set(bundle);
1447                     latch.open();
1448                 },
1449                 sResponseHandler);
1450         intent.putExtra(EXTRA_REMOTE_CALLBACK, callback);
1451         if (waitForReady) {
1452             AmUtils.waitForBroadcastIdle();
1453             startAndWaitForCommandReady(intent);
1454         } else {
1455             InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent);
1456         }
1457         return () -> {
1458             if (!latch.block(TimeUnit.SECONDS.toMillis(10))) {
1459                 throw new TimeoutException(
1460                         "Latch timed out while awiating a response from " + sourcePackageName);
1461             }
1462             final Bundle bundle = resultReference.get();
1463             if (bundle != null && bundle.containsKey(EXTRA_ERROR)) {
1464                 throw (Exception) Objects.requireNonNull(bundle.getSerializable(EXTRA_ERROR));
1465             }
1466             return bundle;
1467         };
1468     }
1469 
1470     private void startAndWaitForCommandReady(Intent intent) throws Exception {
1471         final ConditionVariable latchForReady = new ConditionVariable();
1472         final RemoteCallback readyCallback = new RemoteCallback(bundle -> latchForReady.open(),
1473                 sResponseHandler);
1474         intent.putExtra(EXTRA_REMOTE_READY_CALLBACK, readyCallback);
1475         InstrumentationRegistry.getInstrumentation().getContext().startActivity(intent);
1476         if (!latchForReady.block(TimeUnit.SECONDS.toMillis(10))) {
1477             throw new TimeoutException(
1478                     "Latch timed out while awiating a response from command " + intent.getAction());
1479         }
1480     }
1481 
1482     private Bundle sendCommandBlocking(String sourcePackageName, @Nullable String targetPackageName,
1483             @Nullable Parcelable intentExtra, String action)
1484             throws Exception {
1485         final Result result = sendCommand(sourcePackageName, targetPackageName,
1486                 /* targetUid */ INVALID_UID, intentExtra, action, /* waitForReady */ false);
1487         return result.await();
1488     }
1489 
1490     private Bundle sendCommandBlocking(String sourcePackageName, int targetUid,
1491             @Nullable Parcelable intentExtra, String action)
1492             throws Exception {
1493         final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null,
1494                 targetUid, intentExtra, action, /* waitForReady */ false);
1495         return result.await();
1496     }
1497 
1498     private Result sendCommandAndWaitForLauncherAppsCallback(String sourcePackageName,
1499             int expectedEventCode) throws Exception {
1500         final Bundle extra = new Bundle();
1501         extra.putInt(EXTRA_FLAGS, expectedEventCode);
1502         final Result result = sendCommand(sourcePackageName, /* targetPackageName */ null,
1503                 /* targetUid */ INVALID_UID, extra, ACTION_AWAIT_LAUNCHER_APPS_CALLBACK,
1504                 /* waitForReady */ true);
1505         return result;
1506     }
1507 
1508     private void ensurePackageIsInstalled(String packageName, String apkPath) {
1509         runShellCommand("pm install -R " + apkPath);
1510         PackageInfo info = null;
1511         try {
1512             info = sPm.getPackageInfo(packageName, /* flags */ 0);
1513         } catch (PackageManager.NameNotFoundException e) {
1514             // Ignore
1515         }
1516         Assert.assertNotNull(packageName + " should be installed", info);
1517     }
1518 
1519     private void ensurePackageIsNotInstalled(String packageName) {
1520         runShellCommand("pm uninstall " + packageName);
1521         PackageInfo info = null;
1522         try {
1523             info = sPm.getPackageInfo(packageName, /* flags */ 0);
1524         } catch (PackageManager.NameNotFoundException e) {
1525             // Expected
1526         }
1527         Assert.assertNull(packageName + " shouldn't be installed", info);
1528     }
1529 
1530     private void addPreferredActivity() {
1531         final IntentFilter filter = new IntentFilter(
1532                 "android.intent.action.APP_ENUMERATION_PREFERRED_ACTIVITY");
1533         final ComponentName[] candidates = {new ComponentName(TARGET_PREFERRED_ACTIVITY,
1534                 ACTIVITY_CLASS_DUMMY_ACTIVITY)};
1535         SystemUtil.runWithShellPermissionIdentity(() -> {
1536             sPm.addPreferredActivity(filter, IntentFilter.MATCH_ADJUSTMENT_NORMAL,
1537                     candidates, candidates[0]);
1538         }, SET_PREFERRED_APPLICATIONS);
1539     }
1540 
1541     private void clearPreferredActivity() {
1542         SystemUtil.runWithShellPermissionIdentity(() -> {
1543             sPm.clearPackagePreferredActivities(TARGET_PREFERRED_ACTIVITY);
1544         }, SET_PREFERRED_APPLICATIONS);
1545     }
1546 }
1547