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