• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.appenumeration.cts.Constants.ACTION_CHECK_SIGNATURES;
20 import static android.appenumeration.cts.Constants.ACTION_GET_INSTALLED_PACKAGES;
21 import static android.appenumeration.cts.Constants.ACTION_GET_NAMES_FOR_UIDS;
22 import static android.appenumeration.cts.Constants.ACTION_GET_NAME_FOR_UID;
23 import static android.appenumeration.cts.Constants.ACTION_GET_PACKAGES_FOR_UID;
24 import static android.appenumeration.cts.Constants.ACTION_GET_PACKAGE_INFO;
25 import static android.appenumeration.cts.Constants.ACTION_HAS_SIGNING_CERTIFICATE;
26 import static android.appenumeration.cts.Constants.ACTION_JUST_FINISH;
27 import static android.appenumeration.cts.Constants.ACTION_QUERY_ACTIVITIES;
28 import static android.appenumeration.cts.Constants.ACTION_QUERY_PROVIDERS;
29 import static android.appenumeration.cts.Constants.ACTION_QUERY_SERVICES;
30 import static android.appenumeration.cts.Constants.ACTION_SEND_RESULT;
31 import static android.appenumeration.cts.Constants.ACTION_START_DIRECTLY;
32 import static android.appenumeration.cts.Constants.ACTION_START_FOR_RESULT;
33 import static android.appenumeration.cts.Constants.ACTION_START_SENDER_FOR_RESULT;
34 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_INVALID;
35 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_AVAILABLE;
36 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_SUSPENDED;
37 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_UNAVAILABLE;
38 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_UNSUSPENDED;
39 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_ADDED;
40 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_CHANGED;
41 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_REMOVED;
42 import static android.appenumeration.cts.Constants.EXTRA_ACCOUNT;
43 import static android.appenumeration.cts.Constants.EXTRA_AUTHORITY;
44 import static android.appenumeration.cts.Constants.EXTRA_CERT;
45 import static android.appenumeration.cts.Constants.EXTRA_DATA;
46 import static android.appenumeration.cts.Constants.EXTRA_ERROR;
47 import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
48 import static android.appenumeration.cts.Constants.EXTRA_ID;
49 import static android.appenumeration.cts.Constants.EXTRA_PENDING_INTENT;
50 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK;
51 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_READY_CALLBACK;
52 import static android.content.Intent.EXTRA_COMPONENT_NAME;
53 import static android.content.Intent.EXTRA_PACKAGES;
54 import static android.content.Intent.EXTRA_RETURN_RESULT;
55 import static android.content.Intent.EXTRA_UID;
56 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
57 import static android.os.Process.INVALID_UID;
58 import static android.os.Process.ROOT_UID;
59 
60 import android.accounts.Account;
61 import android.app.Activity;
62 import android.app.AppOpsManager;
63 import android.app.PendingIntent;
64 import android.appwidget.AppWidgetManager;
65 import android.appwidget.AppWidgetProviderInfo;
66 import android.content.ActivityNotFoundException;
67 import android.content.BroadcastReceiver;
68 import android.content.ComponentName;
69 import android.content.ContentResolver;
70 import android.content.Context;
71 import android.content.Intent;
72 import android.content.IntentFilter;
73 import android.content.IntentSender;
74 import android.content.ServiceConnection;
75 import android.content.SyncAdapterType;
76 import android.content.SyncStatusObserver;
77 import android.content.pm.LauncherApps;
78 import android.content.pm.PackageInfo;
79 import android.content.pm.PackageInstaller.SessionCallback;
80 import android.content.pm.PackageInstaller.SessionInfo;
81 import android.content.pm.PackageManager;
82 import android.content.pm.SharedLibraryInfo;
83 import android.database.Cursor;
84 import android.net.Uri;
85 import android.os.Bundle;
86 import android.os.Handler;
87 import android.os.HandlerThread;
88 import android.os.IBinder;
89 import android.os.Parcelable;
90 import android.os.PatternMatcher;
91 import android.os.Process;
92 import android.os.RemoteCallback;
93 import android.os.UserHandle;
94 import android.util.SparseArray;
95 import android.view.accessibility.AccessibilityManager;
96 
97 import java.util.ArrayList;
98 import java.util.Arrays;
99 import java.util.List;
100 import java.util.stream.Collectors;
101 
102 /**
103  *  A test activity running in the query and target applications.
104  */
105 public class TestActivity extends Activity {
106 
107     private final static long TIMEOUT_MS = 3000;
108 
109     /**
110      * Extending the timeout time of non broadcast receivers, avoid not
111      * receiving callbacks in time on some common low-end platforms and
112      * do not affect the situation that callback can be received in advance.
113      */
114     private final static long EXTENDED_TIMEOUT_MS = 5000;
115 
116     SparseArray<RemoteCallback> callbacks = new SparseArray<>();
117 
118     private Handler mainHandler;
119     private Handler backgroundHandler;
120     private HandlerThread backgroundThread;
121     private Object syncStatusHandle;
122 
123     @Override
onCreate(Bundle savedInstanceState)124     protected void onCreate(Bundle savedInstanceState) {
125         mainHandler = new Handler(getMainLooper());
126         backgroundThread = new HandlerThread("testBackground");
127         backgroundThread.start();
128         backgroundHandler = new Handler(backgroundThread.getLooper());
129         super.onCreate(savedInstanceState);
130         handleIntent(getIntent());
131         onCommandReady(getIntent());
132     }
133 
134     @Override
onDestroy()135     protected void onDestroy() {
136         if (syncStatusHandle != null) {
137             ContentResolver.removeStatusChangeListener(syncStatusHandle);
138         }
139         backgroundThread.quitSafely();
140         super.onDestroy();
141     }
142 
handleIntent(Intent intent)143     private void handleIntent(Intent intent) {
144         RemoteCallback remoteCallback = intent.getParcelableExtra(EXTRA_REMOTE_CALLBACK);
145         try {
146             final String action = intent.getAction();
147             final Intent queryIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);
148             if (ACTION_GET_PACKAGE_INFO.equals(action)) {
149                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
150                 sendPackageInfo(remoteCallback, packageName);
151             } else if (ACTION_GET_PACKAGES_FOR_UID.equals(action)) {
152                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
153                 sendPackagesForUid(remoteCallback, uid);
154             } else if (ACTION_GET_NAME_FOR_UID.equals(action)) {
155                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
156                 sendNameForUid(remoteCallback, uid);
157             } else if (ACTION_GET_NAMES_FOR_UIDS.equals(action)) {
158                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
159                 sendNamesForUids(remoteCallback, uid);
160             } else if (ACTION_CHECK_SIGNATURES.equals(action)) {
161                 final int uid1 = getPackageManager().getApplicationInfo(
162                         getPackageName(), /* flags */ 0).uid;
163                 final int uid2 = intent.getIntExtra(EXTRA_UID, INVALID_UID);
164                 sendCheckSignatures(remoteCallback, uid1, uid2);
165             } else if (ACTION_HAS_SIGNING_CERTIFICATE.equals(action)) {
166                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
167                 final byte[] cert = intent.getBundleExtra(EXTRA_DATA).getByteArray(EXTRA_CERT);
168                 sendHasSigningCertificate(remoteCallback, uid, cert, CERT_INPUT_RAW_X509);
169             } else if (ACTION_START_FOR_RESULT.equals(action)) {
170                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
171                 int requestCode = RESULT_FIRST_USER + callbacks.size();
172                 callbacks.put(requestCode, remoteCallback);
173                 startActivityForResult(
174                         new Intent(ACTION_SEND_RESULT).setComponent(
175                                 new ComponentName(packageName, getClass().getCanonicalName())),
176                         requestCode);
177                 // don't send anything... await result callback
178             } else if (ACTION_SEND_RESULT.equals(action)) {
179                 try {
180                     setResult(RESULT_OK,
181                             getIntent().putExtra(
182                                     Intent.EXTRA_RETURN_RESULT,
183                                     getPackageManager().getPackageInfo(getCallingPackage(), 0)));
184                 } catch (PackageManager.NameNotFoundException e) {
185                     setResult(RESULT_FIRST_USER, new Intent().putExtra("error", e));
186                 }
187                 finish();
188             } else if (ACTION_QUERY_ACTIVITIES.equals(action)) {
189                 sendQueryIntentActivities(remoteCallback, queryIntent);
190             } else if (ACTION_QUERY_SERVICES.equals(action)) {
191                 sendQueryIntentServices(remoteCallback, queryIntent);
192             } else if (ACTION_QUERY_PROVIDERS.equals(action)) {
193                 sendQueryIntentProviders(remoteCallback, queryIntent);
194             } else if (ACTION_START_DIRECTLY.equals(action)) {
195                 try {
196                     startActivity(queryIntent);
197                     remoteCallback.sendResult(new Bundle());
198                 } catch (ActivityNotFoundException e) {
199                     sendError(remoteCallback, e);
200                 }
201                 finish();
202             } else if (ACTION_JUST_FINISH.equals(action)) {
203                 finish();
204             } else if (ACTION_GET_INSTALLED_PACKAGES.equals(action)) {
205                 sendGetInstalledPackages(remoteCallback, queryIntent.getIntExtra(EXTRA_FLAGS, 0));
206             } else if (ACTION_START_SENDER_FOR_RESULT.equals(action)) {
207                 PendingIntent pendingIntent = intent.getParcelableExtra(EXTRA_PENDING_INTENT);
208                 int requestCode = RESULT_FIRST_USER + callbacks.size();
209                 callbacks.put(requestCode, remoteCallback);
210                 try {
211                     startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode, null,
212                             0, 0, 0);
213                 } catch (IntentSender.SendIntentException e) {
214                     sendError(remoteCallback, e);
215                 }
216             } else if (Constants.ACTION_AWAIT_PACKAGE_REMOVED.equals(action)) {
217                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
218                 awaitPackageBroadcast(
219                         remoteCallback, packageName, Intent.ACTION_PACKAGE_REMOVED, TIMEOUT_MS);
220             } else if (Constants.ACTION_AWAIT_PACKAGE_ADDED.equals(action)) {
221                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
222                 awaitPackageBroadcast(
223                         remoteCallback, packageName, Intent.ACTION_PACKAGE_ADDED, TIMEOUT_MS);
224             } else if (Constants.ACTION_AWAIT_PACKAGE_FULLY_REMOVED.equals(action)) {
225                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
226                 awaitPackageBroadcast(remoteCallback, packageName,
227                         Intent.ACTION_PACKAGE_FULLY_REMOVED, TIMEOUT_MS);
228             } else if (Constants.ACTION_AWAIT_PACKAGE_DATA_CLEARED.equals(action)) {
229                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
230                 awaitPackageBroadcast(remoteCallback, packageName,
231                         Intent.ACTION_PACKAGE_DATA_CLEARED, TIMEOUT_MS);
232             } else if (Constants.ACTION_QUERY_RESOLVER.equals(action)) {
233                 final String authority = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
234                 queryResolverForVisiblePackages(remoteCallback, authority);
235             } else if (Constants.ACTION_BIND_SERVICE.equals(action)) {
236                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
237                 bindService(remoteCallback, packageName);
238             } else if (Constants.ACTION_GET_SYNCADAPTER_TYPES.equals(action)) {
239                 sendSyncAdapterTypes(remoteCallback);
240             } else if (Constants.ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS.equals(action)) {
241                 sendInstalledAppWidgetProviders(remoteCallback);
242             } else if (Constants.ACTION_AWAIT_PACKAGES_SUSPENDED.equals(action)) {
243                 final String[] awaitPackages = intent.getBundleExtra(EXTRA_DATA)
244                         .getStringArray(EXTRA_PACKAGES);
245                 awaitSuspendedPackagesBroadcast(remoteCallback, Arrays.asList(awaitPackages),
246                         Intent.ACTION_PACKAGES_SUSPENDED, TIMEOUT_MS);
247             } else if (Constants.ACTION_LAUNCHER_APPS_IS_ACTIVITY_ENABLED.equals(action)) {
248                 final String componentName = intent.getBundleExtra(EXTRA_DATA)
249                         .getString(EXTRA_COMPONENT_NAME);
250                 sendIsActivityEnabled(remoteCallback, ComponentName.unflattenFromString(
251                         componentName));
252             } else if (Constants.ACTION_LAUNCHER_APPS_GET_SUSPENDED_PACKAGE_LAUNCHER_EXTRAS.equals(
253                     action)) {
254                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
255                 sendGetSuspendedPackageLauncherExtras(remoteCallback, packageName);
256             } else if (Constants.ACTION_GET_SYNCADAPTER_PACKAGES_FOR_AUTHORITY.equals(action)) {
257                 final String authority = intent.getBundleExtra(EXTRA_DATA)
258                         .getString(EXTRA_AUTHORITY);
259                 final int userId = intent.getBundleExtra(EXTRA_DATA)
260                         .getInt(Intent.EXTRA_USER);
261                 sendSyncAdapterPackagesForAuthorityAsUser(remoteCallback, authority, userId);
262             } else if (Constants.ACTION_REQUEST_SYNC_AND_AWAIT_STATUS.equals(action)) {
263                 final String authority = intent.getBundleExtra(EXTRA_DATA)
264                         .getString(EXTRA_AUTHORITY);
265                 final Account account = intent.getBundleExtra(EXTRA_DATA)
266                         .getParcelable(EXTRA_ACCOUNT);
267                 awaitRequestSyncStatus(remoteCallback, action, account, authority,
268                         EXTENDED_TIMEOUT_MS);
269             } else if (Constants.ACTION_AWAIT_LAUNCHER_APPS_CALLBACK.equals(action)) {
270                 final int expectedEventCode = intent.getBundleExtra(EXTRA_DATA)
271                         .getInt(EXTRA_FLAGS, CALLBACK_EVENT_INVALID);
272                 awaitLauncherAppsCallback(remoteCallback, expectedEventCode, EXTENDED_TIMEOUT_MS);
273             } else if (Constants.ACTION_GET_SHAREDLIBRARY_DEPENDENT_PACKAGES.equals(action)) {
274                 final String sharedLibName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
275                 sendGetSharedLibraryDependentPackages(remoteCallback, sharedLibName);
276             } else if (Constants.ACTION_GET_PREFERRED_ACTIVITIES.equals(action)) {
277                 sendGetPreferredActivities(remoteCallback);
278             } else if (Constants.ACTION_SET_INSTALLER_PACKAGE_NAME.equals(action)) {
279                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
280                 final String installerPackageName = intent.getBundleExtra(EXTRA_DATA)
281                         .getString(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
282                 sendSetInstallerPackageName(remoteCallback, targetPackageName,
283                         installerPackageName);
284             } else if (Constants.ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES.equals(
285                     action)) {
286                 sendGetInstalledAccessibilityServicePackages(remoteCallback);
287             } else if (Constants.ACTION_LAUNCHER_APPS_SHOULD_HIDE_FROM_SUGGESTIONS.equals(action)) {
288                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
289                 final int userId = intent.getBundleExtra(EXTRA_DATA).getInt(Intent.EXTRA_USER);
290                 sendLauncherAppsShouldHideFromSuggestions(remoteCallback, targetPackageName,
291                         userId);
292             } else if (Constants.ACTION_CHECK_URI_PERMISSION.equals(action)) {
293                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
294                 final int targetUid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
295                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
296                         .getString(EXTRA_AUTHORITY);
297                 sendCheckUriPermission(remoteCallback, sourceAuthority, targetPackageName,
298                         targetUid);
299             } else if (Constants.ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
300                 final Uri uri = intent.getData();
301                 final int modeFlags = intent.getFlags();
302                 if (uri != null) {
303                     getContentResolver().takePersistableUriPermission(uri, modeFlags);
304                 }
305                 finish();
306             } else if (Constants.ACTION_CAN_PACKAGE_QUERY.equals(action)) {
307                 final String sourcePackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
308                 final String targetPackageName = intent.getBundleExtra(EXTRA_DATA)
309                         .getString(Intent.EXTRA_PACKAGE_NAME);
310                 sendCanPackageQuery(remoteCallback, sourcePackageName, targetPackageName);
311             } else if (Constants.ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS.equals(action)) {
312                 final List<SessionInfo> infos = getSystemService(LauncherApps.class)
313                         .getAllPackageInstallerSessions();
314                 sendSessionInfosListResult(remoteCallback, infos);
315             } else if (Constants.ACTION_AWAIT_LAUNCHER_APPS_SESSION_CALLBACK.equals(action)) {
316                 final int expectedEventCode = intent.getBundleExtra(EXTRA_DATA)
317                         .getInt(EXTRA_ID, SessionInfo.INVALID_ID);
318                 awaitLauncherAppsSessionCallback(remoteCallback, expectedEventCode,
319                         EXTENDED_TIMEOUT_MS);
320             } else if (Constants.ACTION_GET_SESSION_INFO.equals(action)) {
321                 final int sessionId = intent.getBundleExtra(EXTRA_DATA)
322                         .getInt(EXTRA_ID, SessionInfo.INVALID_ID);
323                 final List<SessionInfo> infos = Arrays.asList(getPackageManager()
324                         .getPackageInstaller()
325                         .getSessionInfo(sessionId));
326                 sendSessionInfosListResult(remoteCallback, infos);
327             } else if (Constants.ACTION_GET_STAGED_SESSIONS.equals(action)) {
328                 final List<SessionInfo> infos = getPackageManager().getPackageInstaller()
329                         .getStagedSessions();
330                 sendSessionInfosListResult(remoteCallback, infos);
331             } else if (Constants.ACTION_GET_ALL_SESSIONS.equals(action)) {
332                 final List<SessionInfo> infos = getPackageManager().getPackageInstaller()
333                         .getAllSessions();
334                 sendSessionInfosListResult(remoteCallback, infos);
335             } else if (Constants.ACTION_PENDING_INTENT_GET_ACTIVITY.equals(action)) {
336                 sendPendingIntentGetActivity(remoteCallback);
337             } else if (Constants.ACTION_PENDING_INTENT_GET_CREATOR_PACKAGE.equals(action)) {
338                 sendPendingIntentGetCreatorPackage(remoteCallback,
339                         intent.getParcelableExtra(EXTRA_PENDING_INTENT));
340             } else if (Constants.ACTION_CHECK_PACKAGE.equals(action)) {
341                 // Using ROOT_UID as default value here to pass the check in #verifyAndGetBypass,
342                 // this is intended by design.
343                 final int uid = intent.getIntExtra(EXTRA_UID, ROOT_UID);
344                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
345                 sendCheckPackageResult(remoteCallback, packageName, uid);
346             } else if (Constants.ACTION_GRANT_URI_PERMISSION.equals(action)) {
347                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
348                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
349                         .getString(EXTRA_AUTHORITY);
350                 sendGrantUriPermission(remoteCallback, sourceAuthority, targetPackageName);
351             } else if (Constants.ACTION_REVOKE_URI_PERMISSION.equals(action)) {
352                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
353                         .getString(EXTRA_AUTHORITY);
354                 sendRevokeUriPermission(remoteCallback, sourceAuthority);
355             } else {
356                 sendError(remoteCallback, new Exception("unknown action " + action));
357             }
358         } catch (Exception e) {
359             sendError(remoteCallback, e);
360         }
361     }
362 
sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback)363     private void sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback) {
364         final String[] packages = getSystemService(
365                 AccessibilityManager.class).getInstalledAccessibilityServiceList().stream().map(
366                 p -> p.getComponentName().getPackageName()).distinct().toArray(String[]::new);
367         final Bundle result = new Bundle();
368         result.putStringArray(EXTRA_RETURN_RESULT, packages);
369         remoteCallback.sendResult(result);
370         finish();
371     }
372 
onCommandReady(Intent intent)373     private void onCommandReady(Intent intent) {
374         final RemoteCallback callback = intent.getParcelableExtra(EXTRA_REMOTE_READY_CALLBACK);
375         if (callback != null) {
376             callback.sendResult(null);
377         }
378     }
379 
awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName, String action, long timeoutMs)380     private void awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName,
381             String action, long timeoutMs) {
382         final IntentFilter filter = new IntentFilter(action);
383         filter.addDataScheme("package");
384         filter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL);
385         final Object token = new Object();
386         registerReceiver(new BroadcastReceiver() {
387             @Override
388             public void onReceive(Context context, Intent intent) {
389                 final Bundle result = new Bundle();
390                 result.putString(EXTRA_DATA, intent.getDataString());
391                 remoteCallback.sendResult(result);
392                 mainHandler.removeCallbacksAndMessages(token);
393                 finish();
394             }
395         }, filter, Context.RECEIVER_EXPORTED_UNAUDITED);
396         mainHandler.postDelayed(
397                 () -> sendError(remoteCallback,
398                         new MissingBroadcastException(action, timeoutMs)),
399                 token, timeoutMs);
400     }
401 
awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback, List<String> awaitList, String action, long timeoutMs)402     private void awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback,
403             List<String> awaitList, String action, long timeoutMs) {
404         final IntentFilter filter = new IntentFilter(action);
405         final ArrayList<String> suspendedList = new ArrayList<>();
406         final Object token = new Object();
407         final Runnable sendResult = () -> {
408             final Bundle result = new Bundle();
409             result.putStringArray(EXTRA_PACKAGES, suspendedList.toArray(new String[] {}));
410             remoteCallback.sendResult(result);
411             finish();
412         };
413         registerReceiver(new BroadcastReceiver() {
414             @Override
415             public void onReceive(Context context, Intent intent) {
416                 final Bundle extras = intent.getExtras();
417                 final String[] changedList = extras.getStringArray(
418                         Intent.EXTRA_CHANGED_PACKAGE_LIST);
419                 suspendedList.addAll(Arrays.stream(changedList).filter(
420                         p -> awaitList.contains(p)).collect(Collectors.toList()));
421                 if (suspendedList.size() == awaitList.size()) {
422                     mainHandler.removeCallbacksAndMessages(token);
423                     sendResult.run();
424                 }
425             }
426         }, filter, Context.RECEIVER_EXPORTED_UNAUDITED);
427         mainHandler.postDelayed(() -> sendResult.run(), token, timeoutMs);
428     }
429 
awaitLauncherAppsCallback(RemoteCallback remoteCallback, int expectedEventCode, long timeoutMs)430     private void awaitLauncherAppsCallback(RemoteCallback remoteCallback, int expectedEventCode,
431             long timeoutMs) {
432         final Object token = new Object();
433         final Bundle result = new Bundle();
434         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
435         final LauncherApps.Callback launcherAppsCallback = new LauncherApps.Callback() {
436 
437             private void onPackageStateUpdated(String[] packageNames, int resultCode) {
438                 if (resultCode != expectedEventCode) {
439                     return;
440                 }
441 
442                 mainHandler.removeCallbacksAndMessages(token);
443                 result.putStringArray(EXTRA_PACKAGES, packageNames);
444                 result.putInt(EXTRA_FLAGS, resultCode);
445                 remoteCallback.sendResult(result);
446 
447                 launcherApps.unregisterCallback(this);
448                 finish();
449             }
450 
451             @Override
452             public void onPackageRemoved(String packageName, UserHandle user) {
453                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_REMOVED);
454             }
455 
456             @Override
457             public void onPackageAdded(String packageName, UserHandle user) {
458                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_ADDED);
459             }
460 
461             @Override
462             public void onPackageChanged(String packageName, UserHandle user) {
463                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_CHANGED);
464             }
465 
466             @Override
467             public void onPackagesAvailable(String[] packageNames, UserHandle user,
468                     boolean replacing) {
469                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_AVAILABLE);
470             }
471 
472             @Override
473             public void onPackagesUnavailable(String[] packageNames, UserHandle user,
474                     boolean replacing) {
475                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_UNAVAILABLE);
476             }
477 
478             @Override
479             public void onPackagesSuspended(String[] packageNames, UserHandle user) {
480                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_SUSPENDED);
481                 super.onPackagesSuspended(packageNames, user);
482             }
483 
484             @Override
485             public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
486                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_UNSUSPENDED);
487                 super.onPackagesUnsuspended(packageNames, user);
488             }
489         };
490 
491         launcherApps.registerCallback(launcherAppsCallback);
492 
493         mainHandler.postDelayed(() -> {
494             result.putStringArray(EXTRA_PACKAGES, new String[]{});
495             result.putInt(EXTRA_FLAGS, CALLBACK_EVENT_INVALID);
496             remoteCallback.sendResult(result);
497 
498             launcherApps.unregisterCallback(launcherAppsCallback);
499             finish();
500         }, token, timeoutMs);
501     }
502 
sendGetInstalledPackages(RemoteCallback remoteCallback, int flags)503     private void sendGetInstalledPackages(RemoteCallback remoteCallback, int flags) {
504         String[] packages =
505                 getPackageManager().getInstalledPackages(flags)
506                         .stream().map(p -> p.packageName).distinct().toArray(String[]::new);
507         Bundle result = new Bundle();
508         result.putStringArray(EXTRA_RETURN_RESULT, packages);
509         remoteCallback.sendResult(result);
510         finish();
511     }
512 
sendQueryIntentActivities(RemoteCallback remoteCallback, Intent queryIntent)513     private void sendQueryIntentActivities(RemoteCallback remoteCallback, Intent queryIntent) {
514         final String[] resolveInfos = getPackageManager().queryIntentActivities(
515                 queryIntent, 0 /* flags */).stream()
516                 .map(ri -> ri.activityInfo.applicationInfo.packageName)
517                 .distinct()
518                 .toArray(String[]::new);
519         Bundle result = new Bundle();
520         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
521         remoteCallback.sendResult(result);
522         finish();
523     }
524 
sendQueryIntentServices(RemoteCallback remoteCallback, Intent queryIntent)525     private void sendQueryIntentServices(RemoteCallback remoteCallback, Intent queryIntent) {
526         final String[] resolveInfos = getPackageManager().queryIntentServices(
527                 queryIntent, 0 /* flags */).stream()
528                 .map(ri -> ri.serviceInfo.applicationInfo.packageName)
529                 .distinct()
530                 .toArray(String[]::new);
531         Bundle result = new Bundle();
532         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
533         remoteCallback.sendResult(result);
534         finish();
535     }
536 
sendQueryIntentProviders(RemoteCallback remoteCallback, Intent queryIntent)537     private void sendQueryIntentProviders(RemoteCallback remoteCallback, Intent queryIntent) {
538         final String[] resolveInfos = getPackageManager().queryIntentContentProviders(
539                 queryIntent, 0 /* flags */).stream()
540                 .map(ri -> ri.providerInfo.applicationInfo.packageName)
541                 .distinct()
542                 .toArray(String[]::new);
543         Bundle result = new Bundle();
544         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
545         remoteCallback.sendResult(result);
546         finish();
547     }
548 
queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority)549     private void queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority) {
550         backgroundHandler.post(() -> {
551             Uri queryUri = Uri.parse("content://" + authority + "/test");
552             Cursor query = getContentResolver().query(queryUri, null, null, null, null);
553             if (query == null || !query.moveToFirst()) {
554                 sendError(remoteCallback,
555                         new IllegalStateException(
556                                 "Query of " + queryUri + " could not be completed"));
557                 return;
558             }
559             ArrayList<String> visiblePackages = new ArrayList<>();
560             while (!query.isAfterLast()) {
561                 visiblePackages.add(query.getString(0));
562                 query.moveToNext();
563             }
564             query.close();
565 
566             mainHandler.post(() -> {
567                 Bundle result = new Bundle();
568                 result.putStringArray(EXTRA_RETURN_RESULT, visiblePackages.toArray(new String[]{}));
569                 remoteCallback.sendResult(result);
570                 finish();
571             });
572 
573         });
574     }
575 
sendError(RemoteCallback remoteCallback, Exception failure)576     private void sendError(RemoteCallback remoteCallback, Exception failure) {
577         Bundle result = new Bundle();
578         result.putSerializable(EXTRA_ERROR, failure);
579         remoteCallback.sendResult(result);
580         finish();
581     }
582 
sendPackageInfo(RemoteCallback remoteCallback, String packageName)583     private void sendPackageInfo(RemoteCallback remoteCallback, String packageName) {
584         final PackageInfo pi;
585         try {
586             pi = getPackageManager().getPackageInfo(packageName, 0);
587         } catch (PackageManager.NameNotFoundException e) {
588             sendError(remoteCallback, e);
589             return;
590         }
591         Bundle result = new Bundle();
592         result.putParcelable(EXTRA_RETURN_RESULT, pi);
593         remoteCallback.sendResult(result);
594         finish();
595     }
596 
sendPackagesForUid(RemoteCallback remoteCallback, int uid)597     private void sendPackagesForUid(RemoteCallback remoteCallback, int uid) {
598         final String[] packages = getPackageManager().getPackagesForUid(uid);
599         final Bundle result = new Bundle();
600         result.putStringArray(EXTRA_RETURN_RESULT, packages);
601         remoteCallback.sendResult(result);
602         finish();
603     }
604 
sendNameForUid(RemoteCallback remoteCallback, int uid)605     private void sendNameForUid(RemoteCallback remoteCallback, int uid) {
606         final String name = getPackageManager().getNameForUid(uid);
607         final Bundle result = new Bundle();
608         result.putString(EXTRA_RETURN_RESULT, name);
609         remoteCallback.sendResult(result);
610         finish();
611     }
612 
sendNamesForUids(RemoteCallback remoteCallback, int uid)613     private void sendNamesForUids(RemoteCallback remoteCallback, int uid) {
614         final String[] names = getPackageManager().getNamesForUids(new int[]{uid});
615         final Bundle result = new Bundle();
616         result.putStringArray(EXTRA_RETURN_RESULT, names);
617         remoteCallback.sendResult(result);
618         finish();
619     }
620 
sendCheckSignatures(RemoteCallback remoteCallback, int uid1, int uid2)621     private void sendCheckSignatures(RemoteCallback remoteCallback, int uid1, int uid2) {
622         final int signatureResult = getPackageManager().checkSignatures(uid1, uid2);
623         final Bundle result = new Bundle();
624         result.putInt(EXTRA_RETURN_RESULT, signatureResult);
625         remoteCallback.sendResult(result);
626         finish();
627     }
628 
sendHasSigningCertificate(RemoteCallback remoteCallback, int uid, byte[] cert, int type)629     private void sendHasSigningCertificate(RemoteCallback remoteCallback, int uid, byte[] cert,
630             int type) {
631         final boolean signatureResult = getPackageManager().hasSigningCertificate(uid, cert, type);
632         final Bundle result = new Bundle();
633         result.putBoolean(EXTRA_RETURN_RESULT, signatureResult);
634         remoteCallback.sendResult(result);
635         finish();
636     }
637 
638     /**
639      * Instead of sending a list of package names, this function sends a List of
640      * {@link SyncAdapterType}, since the {@link SyncAdapterType#getPackageName()} is a test api
641      * which can only be invoked in the instrumentation.
642      */
sendSyncAdapterTypes(RemoteCallback remoteCallback)643     private void sendSyncAdapterTypes(RemoteCallback remoteCallback) {
644         final SyncAdapterType[] types = ContentResolver.getSyncAdapterTypes();
645         final ArrayList<Parcelable> parcelables = new ArrayList<>();
646         for (SyncAdapterType type : types) {
647             parcelables.add(type);
648         }
649         final Bundle result = new Bundle();
650         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
651         remoteCallback.sendResult(result);
652         finish();
653     }
654 
sendIsActivityEnabled(RemoteCallback remoteCallback, ComponentName componentName)655     private void sendIsActivityEnabled(RemoteCallback remoteCallback, ComponentName componentName) {
656         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
657         final Bundle result = new Bundle();
658         try {
659             result.putBoolean(EXTRA_RETURN_RESULT, launcherApps.isActivityEnabled(componentName,
660                     Process.myUserHandle()));
661         } catch (IllegalArgumentException e) {
662         }
663         remoteCallback.sendResult(result);
664         finish();
665     }
666 
sendGetSuspendedPackageLauncherExtras(RemoteCallback remoteCallback, String packageName)667     private void sendGetSuspendedPackageLauncherExtras(RemoteCallback remoteCallback,
668             String packageName) {
669         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
670         final Bundle result = new Bundle();
671         try {
672             result.putBundle(EXTRA_RETURN_RESULT,
673                     launcherApps.getSuspendedPackageLauncherExtras(packageName,
674                             Process.myUserHandle()));
675         } catch (IllegalArgumentException e) {
676         }
677         remoteCallback.sendResult(result);
678         finish();
679     }
680 
sendInstalledAppWidgetProviders(RemoteCallback remoteCallback)681     private void sendInstalledAppWidgetProviders(RemoteCallback remoteCallback) {
682         final AppWidgetManager appWidgetManager = getSystemService(AppWidgetManager.class);
683         final List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
684         final ArrayList<Parcelable> parcelables = new ArrayList<>();
685         for (AppWidgetProviderInfo info : providers) {
686             parcelables.add(info);
687         }
688         final Bundle result = new Bundle();
689         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
690         remoteCallback.sendResult(result);
691         finish();
692     }
693 
sendSyncAdapterPackagesForAuthorityAsUser(RemoteCallback remoteCallback, String authority, int userId)694     private void sendSyncAdapterPackagesForAuthorityAsUser(RemoteCallback remoteCallback,
695             String authority, int userId) {
696         final String[] syncAdapterPackages = ContentResolver
697                 .getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
698         final Bundle result = new Bundle();
699         result.putStringArray(Intent.EXTRA_PACKAGES, syncAdapterPackages);
700         remoteCallback.sendResult(result);
701         finish();
702     }
703 
awaitRequestSyncStatus(RemoteCallback remoteCallback, String action, Account account, String authority, long timeoutMs)704     private void awaitRequestSyncStatus(RemoteCallback remoteCallback, String action,
705             Account account, String authority, long timeoutMs) {
706         ContentResolver.cancelSync(account, authority);
707         final Object token = new Object();
708         final SyncStatusObserver observer = which -> {
709             final Bundle result = new Bundle();
710             result.putBoolean(EXTRA_RETURN_RESULT, true);
711             remoteCallback.sendResult(result);
712             mainHandler.removeCallbacksAndMessages(token);
713             finish();
714         };
715         syncStatusHandle = ContentResolver.addStatusChangeListener(
716                 ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
717                         | ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS
718                         | ContentResolver.SYNC_OBSERVER_TYPE_PENDING, observer);
719 
720         ContentResolver.requestSync(account, authority, new Bundle());
721         mainHandler.postDelayed(
722                 () -> sendError(remoteCallback, new MissingCallbackException(action, timeoutMs)),
723                 token, timeoutMs);
724     }
725 
sendGetSharedLibraryDependentPackages(RemoteCallback remoteCallback, String sharedLibName)726     private void sendGetSharedLibraryDependentPackages(RemoteCallback remoteCallback,
727             String sharedLibName) {
728         final List<SharedLibraryInfo> sharedLibraryInfos = getPackageManager()
729                 .getSharedLibraries(0 /* flags */);
730         SharedLibraryInfo sharedLibraryInfo = sharedLibraryInfos.stream().filter(
731                 info -> sharedLibName.equals(info.getName())).findAny().orElse(null);
732         final String[] dependentPackages = sharedLibraryInfo == null ? null
733                 : sharedLibraryInfo.getDependentPackages().stream()
734                         .map(versionedPackage -> versionedPackage.getPackageName())
735                         .distinct().collect(Collectors.toList()).toArray(new String[]{});
736         final Bundle result = new Bundle();
737         result.putStringArray(Intent.EXTRA_PACKAGES, dependentPackages);
738         remoteCallback.sendResult(result);
739         finish();
740     }
741 
sendGetPreferredActivities(RemoteCallback remoteCallback)742     private void sendGetPreferredActivities(RemoteCallback remoteCallback) {
743         final List<IntentFilter> filters = new ArrayList<>();
744         final List<ComponentName> activities = new ArrayList<>();
745         getPackageManager().getPreferredActivities(filters, activities, null /* packageName*/);
746         final String[] packages = activities.stream()
747                 .map(componentName -> componentName.getPackageName()).distinct()
748                 .collect(Collectors.toList()).toArray(new String[]{});
749         final Bundle result = new Bundle();
750         result.putStringArray(Intent.EXTRA_PACKAGES, packages);
751         remoteCallback.sendResult(result);
752         finish();
753     }
754 
sendSetInstallerPackageName(RemoteCallback remoteCallback, String targetPackageName, String installerPackageName)755     private void sendSetInstallerPackageName(RemoteCallback remoteCallback,
756             String targetPackageName, String installerPackageName) {
757         try {
758             getPackageManager().setInstallerPackageName(targetPackageName, installerPackageName);
759             remoteCallback.sendResult(null);
760             finish();
761         } catch (Exception e) {
762             sendError(remoteCallback, e);
763         }
764     }
765 
sendLauncherAppsShouldHideFromSuggestions(RemoteCallback remoteCallback, String targetPackageName, int userId)766     private void sendLauncherAppsShouldHideFromSuggestions(RemoteCallback remoteCallback,
767             String targetPackageName, int userId) {
768         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
769         final boolean hideFromSuggestions = launcherApps.shouldHideFromSuggestions(
770                 targetPackageName, UserHandle.of(userId));
771         final Bundle result = new Bundle();
772         result.putBoolean(EXTRA_RETURN_RESULT, hideFromSuggestions);
773         remoteCallback.sendResult(result);
774         finish();
775     }
776 
sendCheckUriPermission(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName, int targetUid)777     private void sendCheckUriPermission(RemoteCallback remoteCallback, String sourceAuthority,
778             String targetPackageName, int targetUid) {
779         final Uri uri = Uri.parse("content://" + sourceAuthority);
780         grantUriPermission(targetPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
781         final int permissionResult = checkUriPermission(uri, 0 /* pid */, targetUid,
782                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
783         revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
784         final Bundle result = new Bundle();
785         result.putInt(EXTRA_RETURN_RESULT, permissionResult);
786         remoteCallback.sendResult(result);
787         finish();
788     }
789 
sendGrantUriPermission(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName)790     private void sendGrantUriPermission(RemoteCallback remoteCallback, String sourceAuthority,
791             String targetPackageName) {
792         final Uri uri = Uri.parse("content://" + sourceAuthority);
793         grantUriPermission(targetPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
794         remoteCallback.sendResult(null);
795         finish();
796     }
797 
sendRevokeUriPermission(RemoteCallback remoteCallback, String sourceAuthority)798     private void sendRevokeUriPermission(RemoteCallback remoteCallback, String sourceAuthority) {
799         final Uri uri = Uri.parse("content://" + sourceAuthority);
800         revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
801         remoteCallback.sendResult(null);
802         finish();
803     }
804 
sendCanPackageQuery(RemoteCallback remoteCallback, String sourcePackageName, String targetPackageName)805     private void sendCanPackageQuery(RemoteCallback remoteCallback, String sourcePackageName,
806             String targetPackageName) {
807         try {
808             final boolean visibility = getPackageManager().canPackageQuery(sourcePackageName,
809                     targetPackageName);
810             final Bundle result = new Bundle();
811             result.putBoolean(EXTRA_RETURN_RESULT, visibility);
812             remoteCallback.sendResult(result);
813             finish();
814         } catch (PackageManager.NameNotFoundException e) {
815             sendError(remoteCallback, e);
816         }
817     }
818 
sendSessionInfosListResult(RemoteCallback remoteCallback, List<SessionInfo> infos)819     private void sendSessionInfosListResult(RemoteCallback remoteCallback,
820             List<SessionInfo> infos) {
821         final ArrayList<Parcelable> parcelables = new ArrayList<>(infos);
822         for (SessionInfo info : infos) {
823             parcelables.add(info);
824         }
825         final Bundle result = new Bundle();
826         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
827         remoteCallback.sendResult(result);
828         finish();
829     }
830 
awaitLauncherAppsSessionCallback(RemoteCallback remoteCallback, int expectedSessionId, long timeoutMs)831     private void awaitLauncherAppsSessionCallback(RemoteCallback remoteCallback,
832             int expectedSessionId, long timeoutMs) {
833         final Object token = new Object();
834         final Bundle result = new Bundle();
835         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
836         final SessionCallback sessionCallback = new SessionCallback() {
837 
838             @Override
839             public void onCreated(int sessionId) {
840                 // No-op
841             }
842 
843             @Override
844             public void onBadgingChanged(int sessionId) {
845                 // No-op
846             }
847 
848             @Override
849             public void onActiveChanged(int sessionId, boolean active) {
850                 // No-op
851             }
852 
853             @Override
854             public void onProgressChanged(int sessionId, float progress) {
855                 // No-op
856             }
857 
858             @Override
859             public void onFinished(int sessionId, boolean success) {
860                 if (sessionId != expectedSessionId) {
861                     return;
862                 }
863 
864                 mainHandler.removeCallbacksAndMessages(token);
865                 result.putInt(EXTRA_ID, sessionId);
866                 remoteCallback.sendResult(result);
867 
868                 launcherApps.unregisterPackageInstallerSessionCallback(this);
869                 finish();
870             }
871         };
872 
873         launcherApps.registerPackageInstallerSessionCallback(this.getMainExecutor(),
874                 sessionCallback);
875 
876         mainHandler.postDelayed(() -> {
877             result.putInt(EXTRA_ID, SessionInfo.INVALID_ID);
878             remoteCallback.sendResult(result);
879 
880             launcherApps.unregisterPackageInstallerSessionCallback(sessionCallback);
881             finish();
882         }, token, timeoutMs);
883     }
884 
sendPendingIntentGetActivity(RemoteCallback remoteCallback)885     private void sendPendingIntentGetActivity(RemoteCallback remoteCallback) {
886         final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* requestCode */,
887                 new Intent(this, TestActivity.class), PendingIntent.FLAG_IMMUTABLE);
888         final Bundle result = new Bundle();
889         result.putParcelable(EXTRA_PENDING_INTENT, pendingIntent);
890         remoteCallback.sendResult(result);
891         finish();
892     }
893 
sendPendingIntentGetCreatorPackage(RemoteCallback remoteCallback, PendingIntent pendingIntent)894     private void sendPendingIntentGetCreatorPackage(RemoteCallback remoteCallback,
895             PendingIntent pendingIntent) {
896         final Bundle result = new Bundle();
897         result.putString(Intent.EXTRA_PACKAGE_NAME, pendingIntent.getCreatorPackage());
898         remoteCallback.sendResult(result);
899         finish();
900     }
901 
sendCheckPackageResult(RemoteCallback remoteCallback, String packageName, int uid)902     private void sendCheckPackageResult(RemoteCallback remoteCallback, String packageName,
903             int uid) {
904         try {
905             getSystemService(AppOpsManager.class).checkPackage(uid, packageName);
906             final Bundle result = new Bundle();
907             result.putBoolean(EXTRA_RETURN_RESULT, true);
908             remoteCallback.sendResult(result);
909             finish();
910         } catch (SecurityException e) {
911             sendError(remoteCallback, e);
912         }
913     }
914 
915     @Override
onActivityResult(int requestCode, int resultCode, Intent data)916     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
917         super.onActivityResult(requestCode, resultCode, data);
918         final RemoteCallback remoteCallback = callbacks.get(requestCode);
919         if (resultCode != RESULT_OK) {
920             Exception e = (Exception) data.getSerializableExtra(EXTRA_ERROR);
921             sendError(remoteCallback, e == null ? new Exception("Result was " + resultCode) : e);
922             return;
923         }
924         final Bundle result = new Bundle();
925         result.putParcelable(EXTRA_RETURN_RESULT, data.getParcelableExtra(EXTRA_RETURN_RESULT));
926         remoteCallback.sendResult(result);
927         finish();
928     }
929 
bindService(RemoteCallback remoteCallback, String packageName)930     private void bindService(RemoteCallback remoteCallback, String packageName) {
931         final String SERVICE_NAME = "android.appenumeration.testapp.DummyService";
932         final Intent intent = new Intent();
933         intent.setClassName(packageName, SERVICE_NAME);
934         final ServiceConnection serviceConnection = new ServiceConnection() {
935             @Override
936             public void onServiceConnected(ComponentName className, IBinder service) {
937                 // No-op
938             }
939 
940             @Override
941             public void onServiceDisconnected(ComponentName className) {
942                 // No-op
943             }
944 
945             @Override
946             public void onBindingDied(ComponentName name) {
947                 // Remote service die
948                 finish();
949             }
950 
951             @Override
952             public void onNullBinding(ComponentName name) {
953                 // Since the DummyService doesn't implement onBind, it returns null and
954                 // onNullBinding would be called. Use postDelayed to keep this service
955                 // connection alive for 3 seconds.
956                 mainHandler.postDelayed(() -> {
957                     unbindService(this);
958                     finish();
959                 }, TIMEOUT_MS);
960             }
961         };
962 
963         final boolean bound = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
964         final Bundle result = new Bundle();
965         result.putBoolean(EXTRA_RETURN_RESULT, bound);
966         remoteCallback.sendResult(result);
967         // Don't invoke finish() right here if service is bound successfully to keep the service
968         // connection alive since the ServiceRecord would be remove from the ServiceMap once no
969         // client is binding the service.
970         if (!bound) finish();
971     }
972 }
973