• 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_MANIFEST_SERVICE;
28 import static android.appenumeration.cts.Constants.ACTION_MEDIA_SESSION_MANAGER_IS_TRUSTED_FOR_MEDIA_CONTROL;
29 import static android.appenumeration.cts.Constants.ACTION_QUERY_ACTIVITIES;
30 import static android.appenumeration.cts.Constants.ACTION_QUERY_PROVIDERS;
31 import static android.appenumeration.cts.Constants.ACTION_QUERY_SERVICES;
32 import static android.appenumeration.cts.Constants.ACTION_SEND_RESULT;
33 import static android.appenumeration.cts.Constants.ACTION_START_DIRECTLY;
34 import static android.appenumeration.cts.Constants.ACTION_START_FOR_RESULT;
35 import static android.appenumeration.cts.Constants.ACTION_START_SENDER_FOR_RESULT;
36 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_INVALID;
37 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_AVAILABLE;
38 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_SUSPENDED;
39 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_UNAVAILABLE;
40 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGES_UNSUSPENDED;
41 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_ADDED;
42 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_CHANGED;
43 import static android.appenumeration.cts.Constants.CALLBACK_EVENT_PACKAGE_REMOVED;
44 import static android.appenumeration.cts.Constants.EXTRA_ACCOUNT;
45 import static android.appenumeration.cts.Constants.EXTRA_AUTHORITY;
46 import static android.appenumeration.cts.Constants.EXTRA_CERT;
47 import static android.appenumeration.cts.Constants.EXTRA_DATA;
48 import static android.appenumeration.cts.Constants.EXTRA_ERROR;
49 import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
50 import static android.appenumeration.cts.Constants.EXTRA_ID;
51 import static android.appenumeration.cts.Constants.EXTRA_INPUT_METHOD_INFO;
52 import static android.appenumeration.cts.Constants.EXTRA_PENDING_INTENT;
53 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_CALLBACK;
54 import static android.appenumeration.cts.Constants.EXTRA_REMOTE_READY_CALLBACK;
55 import static android.appenumeration.cts.Constants.EXTRA_SEGMENT_RESULT;
56 import static android.appenumeration.cts.Constants.EXTRA_SEGMENT_SIZE;
57 import static android.appenumeration.cts.Constants.SERVICE_CLASS_DUMMY_SERVICE;
58 import static android.content.Intent.EXTRA_COMPONENT_NAME;
59 import static android.content.Intent.EXTRA_PACKAGES;
60 import static android.content.Intent.EXTRA_RETURN_RESULT;
61 import static android.content.Intent.EXTRA_UID;
62 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
63 import static android.os.Process.INVALID_UID;
64 import static android.os.Process.ROOT_UID;
65 
66 import android.accounts.Account;
67 import android.accounts.AccountManager;
68 import android.app.Activity;
69 import android.app.ActivityManager;
70 import android.app.AppOpsManager;
71 import android.app.PendingIntent;
72 import android.appwidget.AppWidgetManager;
73 import android.appwidget.AppWidgetProviderInfo;
74 import android.content.ActivityNotFoundException;
75 import android.content.BroadcastReceiver;
76 import android.content.ComponentName;
77 import android.content.ContentResolver;
78 import android.content.Context;
79 import android.content.Intent;
80 import android.content.IntentFilter;
81 import android.content.IntentSender;
82 import android.content.PeriodicSync;
83 import android.content.ServiceConnection;
84 import android.content.SyncAdapterType;
85 import android.content.SyncStatusObserver;
86 import android.content.pm.LauncherApps;
87 import android.content.pm.PackageInfo;
88 import android.content.pm.PackageInstaller.SessionCallback;
89 import android.content.pm.PackageInstaller.SessionInfo;
90 import android.content.pm.PackageManager;
91 import android.content.pm.PackageManager.ApplicationInfoFlags;
92 import android.content.pm.PackageManager.PackageInfoFlags;
93 import android.content.pm.PackageManager.ResolveInfoFlags;
94 import android.content.pm.SharedLibraryInfo;
95 import android.database.Cursor;
96 import android.media.session.MediaSessionManager;
97 import android.net.Uri;
98 import android.os.Bundle;
99 import android.os.Handler;
100 import android.os.HandlerThread;
101 import android.os.IBinder;
102 import android.os.Parcelable;
103 import android.os.PatternMatcher;
104 import android.os.Process;
105 import android.os.RemoteCallback;
106 import android.os.UserHandle;
107 import android.util.SparseArray;
108 import android.view.accessibility.AccessibilityManager;
109 import android.view.inputmethod.InputMethodInfo;
110 import android.view.inputmethod.InputMethodManager;
111 import android.view.inputmethod.InputMethodSubtype;
112 import android.view.textservice.SpellCheckerInfo;
113 import android.view.textservice.TextServicesManager;
114 
115 import java.util.ArrayList;
116 import java.util.Arrays;
117 import java.util.List;
118 import java.util.concurrent.TimeUnit;
119 import java.util.stream.Collectors;
120 
121 /**
122  *  A test activity running in the query and target applications.
123  */
124 public class TestActivity extends Activity {
125 
126     private final static long TIMEOUT_MS = 3000;
127 
128     /**
129      * Extending the timeout time of non broadcast receivers, avoid not
130      * receiving callbacks in time on some common low-end platforms and
131      * do not affect the situation that callback can be received in advance.
132      */
133     private final static long EXTENDED_TIMEOUT_MS = 7000;
134 
135     SparseArray<RemoteCallback> callbacks = new SparseArray<>();
136 
137     private Handler mainHandler;
138     private Handler backgroundHandler;
139     private HandlerThread backgroundThread;
140     private Object syncStatusHandle;
141 
142     @Override
onCreate(Bundle savedInstanceState)143     protected void onCreate(Bundle savedInstanceState) {
144         mainHandler = new Handler(getMainLooper());
145         backgroundThread = new HandlerThread("testBackground");
146         backgroundThread.start();
147         backgroundHandler = new Handler(backgroundThread.getLooper());
148         super.onCreate(savedInstanceState);
149         handleIntent(getIntent());
150         onCommandReady(getIntent());
151     }
152 
153     @Override
onDestroy()154     protected void onDestroy() {
155         if (syncStatusHandle != null) {
156             ContentResolver.removeStatusChangeListener(syncStatusHandle);
157         }
158         backgroundThread.quitSafely();
159         super.onDestroy();
160     }
161 
handleIntent(Intent intent)162     private void handleIntent(Intent intent) {
163         final RemoteCallback remoteCallback = intent.getParcelableExtra(EXTRA_REMOTE_CALLBACK,
164                 RemoteCallback.class);
165         try {
166             final String action = intent.getAction();
167             final Intent queryIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class);
168             if (ACTION_GET_PACKAGE_INFO.equals(action)) {
169                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
170                 sendPackageInfo(remoteCallback, packageName);
171             } else if (ACTION_GET_PACKAGES_FOR_UID.equals(action)) {
172                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
173                 sendPackagesForUid(remoteCallback, uid);
174             } else if (ACTION_GET_NAME_FOR_UID.equals(action)) {
175                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
176                 sendNameForUid(remoteCallback, uid);
177             } else if (ACTION_GET_NAMES_FOR_UIDS.equals(action)) {
178                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
179                 sendNamesForUids(remoteCallback, uid);
180             } else if (ACTION_CHECK_SIGNATURES.equals(action)) {
181                 final int uid1 = getPackageManager().getApplicationInfo(
182                         getPackageName(), ApplicationInfoFlags.of(0)).uid;
183                 final int uid2 = intent.getIntExtra(EXTRA_UID, INVALID_UID);
184                 sendCheckSignatures(remoteCallback, uid1, uid2);
185             } else if (ACTION_HAS_SIGNING_CERTIFICATE.equals(action)) {
186                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
187                 final byte[] cert = intent.getBundleExtra(EXTRA_DATA).getByteArray(EXTRA_CERT);
188                 sendHasSigningCertificate(remoteCallback, uid, cert, CERT_INPUT_RAW_X509);
189             } else if (ACTION_START_FOR_RESULT.equals(action)) {
190                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
191                 int requestCode = RESULT_FIRST_USER + callbacks.size();
192                 callbacks.put(requestCode, remoteCallback);
193                 startActivityForResult(
194                         new Intent(ACTION_SEND_RESULT).setComponent(
195                                 new ComponentName(packageName, getClass().getCanonicalName())),
196                         requestCode);
197                 // don't send anything... await result callback
198             } else if (ACTION_SEND_RESULT.equals(action)) {
199                 try {
200                     setResult(RESULT_OK,
201                             getIntent().putExtra(
202                                     Intent.EXTRA_RETURN_RESULT,
203                                     getPackageManager().getPackageInfo(getCallingPackage(),
204                                             PackageInfoFlags.of(0))));
205                 } catch (PackageManager.NameNotFoundException e) {
206                     setResult(RESULT_FIRST_USER, new Intent().putExtra("error", e));
207                 }
208                 finish();
209             } else if (ACTION_QUERY_ACTIVITIES.equals(action)) {
210                 sendQueryIntentActivities(remoteCallback, queryIntent);
211             } else if (ACTION_QUERY_SERVICES.equals(action)) {
212                 sendQueryIntentServices(remoteCallback, queryIntent);
213             } else if (ACTION_QUERY_PROVIDERS.equals(action)) {
214                 sendQueryIntentProviders(remoteCallback, queryIntent);
215             } else if (ACTION_START_DIRECTLY.equals(action)) {
216                 try {
217                     startActivity(queryIntent);
218                     remoteCallback.sendResult(new Bundle());
219                 } catch (ActivityNotFoundException e) {
220                     sendError(remoteCallback, e);
221                 }
222                 finish();
223             } else if (ACTION_JUST_FINISH.equals(action)) {
224                 finish();
225             } else if (ACTION_GET_INSTALLED_PACKAGES.equals(action)) {
226                 sendGetInstalledPackages(remoteCallback, queryIntent.getIntExtra(EXTRA_FLAGS, 0));
227             } else if (ACTION_START_SENDER_FOR_RESULT.equals(action)) {
228                 final PendingIntent pendingIntent = intent.getParcelableExtra(EXTRA_PENDING_INTENT,
229                         PendingIntent.class);
230                 int requestCode = RESULT_FIRST_USER + callbacks.size();
231                 callbacks.put(requestCode, remoteCallback);
232                 try {
233                     startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode, null,
234                             0, 0, 0);
235                 } catch (IntentSender.SendIntentException e) {
236                     sendError(remoteCallback, e);
237                 }
238             } else if (Constants.ACTION_AWAIT_PACKAGE_REMOVED.equals(action)) {
239                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
240                 awaitPackageBroadcast(
241                         remoteCallback, packageName, Intent.ACTION_PACKAGE_REMOVED, TIMEOUT_MS);
242             } else if (Constants.ACTION_AWAIT_PACKAGE_ADDED.equals(action)) {
243                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
244                 awaitPackageBroadcast(
245                         remoteCallback, packageName, Intent.ACTION_PACKAGE_ADDED, TIMEOUT_MS);
246             } else if (Constants.ACTION_AWAIT_PACKAGE_FULLY_REMOVED.equals(action)) {
247                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
248                 awaitPackageBroadcast(remoteCallback, packageName,
249                         Intent.ACTION_PACKAGE_FULLY_REMOVED, TIMEOUT_MS);
250             } else if (Constants.ACTION_AWAIT_PACKAGE_DATA_CLEARED.equals(action)) {
251                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
252                 awaitPackageBroadcast(remoteCallback, packageName,
253                         Intent.ACTION_PACKAGE_DATA_CLEARED, TIMEOUT_MS);
254             } else if (Constants.ACTION_QUERY_RESOLVER.equals(action)) {
255                 final String authority = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
256                 queryResolverForVisiblePackages(remoteCallback, authority);
257             } else if (Constants.ACTION_BIND_SERVICE.equals(action)) {
258                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
259                 bindService(remoteCallback, packageName);
260             } else if (Constants.ACTION_GET_SYNCADAPTER_TYPES.equals(action)) {
261                 sendSyncAdapterTypes(remoteCallback);
262             } else if (Constants.ACTION_GET_INSTALLED_APPWIDGET_PROVIDERS.equals(action)) {
263                 sendInstalledAppWidgetProviders(remoteCallback);
264             } else if (Constants.ACTION_AWAIT_PACKAGES_SUSPENDED.equals(action)) {
265                 final String[] awaitPackages = intent.getBundleExtra(EXTRA_DATA)
266                         .getStringArray(EXTRA_PACKAGES);
267                 awaitSuspendedPackagesBroadcast(remoteCallback, Arrays.asList(awaitPackages),
268                         Intent.ACTION_PACKAGES_SUSPENDED, TIMEOUT_MS);
269             } else if (Constants.ACTION_LAUNCHER_APPS_IS_ACTIVITY_ENABLED.equals(action)) {
270                 final String componentName = intent.getBundleExtra(EXTRA_DATA)
271                         .getString(EXTRA_COMPONENT_NAME);
272                 sendIsActivityEnabled(remoteCallback, ComponentName.unflattenFromString(
273                         componentName));
274             } else if (Constants.ACTION_LAUNCHER_APPS_GET_SUSPENDED_PACKAGE_LAUNCHER_EXTRAS.equals(
275                     action)) {
276                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
277                 sendGetSuspendedPackageLauncherExtras(remoteCallback, packageName);
278             } else if (Constants.ACTION_GET_SYNCADAPTER_PACKAGES_FOR_AUTHORITY.equals(action)) {
279                 final String authority = intent.getBundleExtra(EXTRA_DATA)
280                         .getString(EXTRA_AUTHORITY);
281                 final int userId = intent.getBundleExtra(EXTRA_DATA)
282                         .getInt(Intent.EXTRA_USER);
283                 sendSyncAdapterPackagesForAuthorityAsUser(remoteCallback, authority, userId);
284             } else if (Constants.ACTION_REQUEST_SYNC_AND_AWAIT_STATUS.equals(action)) {
285                 final String authority = intent.getBundleExtra(EXTRA_DATA)
286                         .getString(EXTRA_AUTHORITY);
287                 final Account account = intent.getBundleExtra(EXTRA_DATA)
288                         .getParcelable(EXTRA_ACCOUNT, Account.class);
289                 awaitRequestSyncStatus(remoteCallback, action, account, authority,
290                         EXTENDED_TIMEOUT_MS);
291             } else if (Constants.ACTION_GET_SYNCADAPTER_CONTROL_PANEL.equals(action)) {
292                 final String authority = intent.getBundleExtra(EXTRA_DATA)
293                         .getString(EXTRA_AUTHORITY);
294                 final Account account = intent.getBundleExtra(EXTRA_DATA)
295                         .getParcelable(EXTRA_ACCOUNT, Account.class);
296                 final ComponentName componentName = intent.getBundleExtra(EXTRA_DATA)
297                         .getParcelable(EXTRA_COMPONENT_NAME, ComponentName.class);
298                 sendGetSyncAdapterControlPanel(remoteCallback, account, authority, componentName);
299             } else if (Constants.ACTION_REQUEST_PERIODIC_SYNC.equals(action)) {
300                 final Account account = intent.getBundleExtra(EXTRA_DATA)
301                         .getParcelable(EXTRA_ACCOUNT, Account.class);
302                 final String authority = intent.getBundleExtra(EXTRA_DATA)
303                         .getString(EXTRA_AUTHORITY);
304                 awaitRequestPeriodicSync(remoteCallback, account, authority,
305                         TimeUnit.SECONDS.toMillis(15));
306             } else if (Constants.ACTION_SET_SYNC_AUTOMATICALLY.equals(action)) {
307                 final Account account = intent.getBundleExtra(EXTRA_DATA)
308                         .getParcelable(EXTRA_ACCOUNT, Account.class);
309                 final String authority = intent.getBundleExtra(EXTRA_DATA)
310                         .getString(EXTRA_AUTHORITY);
311                 setSyncAutomatically(remoteCallback, account, authority);
312             } else if (Constants.ACTION_GET_SYNC_AUTOMATICALLY.equals(action)) {
313                 final String authority = intent.getBundleExtra(EXTRA_DATA)
314                         .getString(EXTRA_AUTHORITY);
315                 getSyncAutomatically(remoteCallback, authority);
316             } else if (Constants.ACTION_GET_IS_SYNCABLE.equals(action)) {
317                 final Account account = intent.getBundleExtra(EXTRA_DATA)
318                         .getParcelable(EXTRA_ACCOUNT, Account.class);
319                 final String authority = intent.getBundleExtra(EXTRA_DATA)
320                         .getString(EXTRA_AUTHORITY);
321                 getIsSyncable(remoteCallback, account, authority);
322             } else if (Constants.ACTION_GET_PERIODIC_SYNCS.equals(action)) {
323                 final Account account = intent.getBundleExtra(EXTRA_DATA)
324                         .getParcelable(EXTRA_ACCOUNT, Account.class);
325                 final String authority = intent.getBundleExtra(EXTRA_DATA)
326                         .getString(EXTRA_AUTHORITY);
327                 getPeriodicSyncs(remoteCallback, account, authority);
328             } else if (Constants.ACTION_AWAIT_LAUNCHER_APPS_CALLBACK.equals(action)) {
329                 final int expectedEventCode = intent.getBundleExtra(EXTRA_DATA)
330                         .getInt(EXTRA_FLAGS, CALLBACK_EVENT_INVALID);
331                 final String[] expectedPackages = intent.getBundleExtra(EXTRA_DATA)
332                         .getStringArray(EXTRA_PACKAGES);
333                 awaitLauncherAppsCallback(remoteCallback, expectedEventCode, expectedPackages,
334                         EXTENDED_TIMEOUT_MS);
335             } else if (Constants.ACTION_GET_SHAREDLIBRARY_DEPENDENT_PACKAGES.equals(action)) {
336                 final String sharedLibName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
337                 sendGetSharedLibraryDependentPackages(remoteCallback, sharedLibName);
338             } else if (Constants.ACTION_GET_PREFERRED_ACTIVITIES.equals(action)) {
339                 sendGetPreferredActivities(remoteCallback);
340             } else if (Constants.ACTION_SET_INSTALLER_PACKAGE_NAME.equals(action)) {
341                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
342                 final String installerPackageName = intent.getBundleExtra(EXTRA_DATA)
343                         .getString(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
344                 sendSetInstallerPackageName(remoteCallback, targetPackageName,
345                         installerPackageName);
346             } else if (Constants.ACTION_GET_INSTALLED_ACCESSIBILITYSERVICES_PACKAGES.equals(
347                     action)) {
348                 sendGetInstalledAccessibilityServicePackages(remoteCallback);
349             } else if (Constants.ACTION_LAUNCHER_APPS_SHOULD_HIDE_FROM_SUGGESTIONS.equals(action)) {
350                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
351                 final int userId = intent.getBundleExtra(EXTRA_DATA).getInt(Intent.EXTRA_USER);
352                 sendLauncherAppsShouldHideFromSuggestions(remoteCallback, targetPackageName,
353                         userId);
354             } else if (Constants.ACTION_CHECK_URI_PERMISSION.equals(action)) {
355                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
356                 final int targetUid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
357                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
358                         .getString(EXTRA_AUTHORITY);
359                 sendCheckUriPermission(remoteCallback, sourceAuthority, targetPackageName,
360                         targetUid);
361             } else if (Constants.ACTION_CHECK_CONTENT_URI_PERMISSION_FULL.equals(action)) {
362                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
363                 final int targetUid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
364                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
365                         .getString(EXTRA_AUTHORITY);
366                 sendCheckContentUriPermissionFull(remoteCallback, sourceAuthority,
367                         targetPackageName, targetUid);
368             } else if (Constants.ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
369                 final Uri uri = intent.getData();
370                 final int modeFlags = intent.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION
371                         | Intent.FLAG_GRANT_READ_URI_PERMISSION);
372                 if (uri != null) {
373                     getContentResolver().takePersistableUriPermission(uri, modeFlags);
374                 }
375                 finish();
376             } else if (Constants.ACTION_CAN_PACKAGE_QUERY.equals(action)) {
377                 final String sourcePackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
378                 final String targetPackageName = intent.getBundleExtra(EXTRA_DATA)
379                         .getString(Intent.EXTRA_PACKAGE_NAME);
380                 sendCanPackageQuery(remoteCallback, sourcePackageName, targetPackageName);
381             } else if (Constants.ACTION_CAN_PACKAGE_QUERIES.equals(action)) {
382                 final String sourcePackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
383                 final String[] targetPackageNames = intent.getBundleExtra(EXTRA_DATA)
384                         .getStringArray(EXTRA_PACKAGES);
385                 sendCanPackageQueries(remoteCallback, sourcePackageName, targetPackageNames);
386             } else if (Constants.ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS.equals(action)) {
387                 final List<SessionInfo> infos = getSystemService(LauncherApps.class)
388                         .getAllPackageInstallerSessions();
389                 sendSessionInfosListResult(remoteCallback, infos);
390             } else if (Constants.ACTION_AWAIT_LAUNCHER_APPS_SESSION_CALLBACK.equals(action)) {
391                 final int expectedEventCode = intent.getBundleExtra(EXTRA_DATA)
392                         .getInt(EXTRA_ID, SessionInfo.INVALID_ID);
393                 awaitLauncherAppsSessionCallback(remoteCallback, expectedEventCode,
394                         EXTENDED_TIMEOUT_MS);
395             } else if (Constants.ACTION_GET_SESSION_INFO.equals(action)) {
396                 final int sessionId = intent.getBundleExtra(EXTRA_DATA)
397                         .getInt(EXTRA_ID, SessionInfo.INVALID_ID);
398                 final List<SessionInfo> infos = Arrays.asList(getPackageManager()
399                         .getPackageInstaller()
400                         .getSessionInfo(sessionId));
401                 sendSessionInfosListResult(remoteCallback, infos);
402             } else if (Constants.ACTION_GET_STAGED_SESSIONS.equals(action)) {
403                 final List<SessionInfo> infos = getPackageManager().getPackageInstaller()
404                         .getStagedSessions();
405                 sendSessionInfosListResult(remoteCallback, infos);
406             } else if (Constants.ACTION_GET_ALL_SESSIONS.equals(action)) {
407                 final List<SessionInfo> infos = getPackageManager().getPackageInstaller()
408                         .getAllSessions();
409                 sendSessionInfosListResult(remoteCallback, infos);
410             } else if (Constants.ACTION_PENDING_INTENT_GET_ACTIVITY.equals(action)) {
411                 sendPendingIntentGetActivity(remoteCallback);
412             } else if (Constants.ACTION_PENDING_INTENT_GET_CREATOR_PACKAGE.equals(action)) {
413                 sendPendingIntentGetCreatorPackage(remoteCallback,
414                         intent.getParcelableExtra(EXTRA_PENDING_INTENT, PendingIntent.class));
415             } else if (Constants.ACTION_CHECK_PACKAGE.equals(action)) {
416                 // Using ROOT_UID as default value here to pass the check in #verifyAndGetBypass,
417                 // this is intended by design.
418                 final int uid = intent.getIntExtra(EXTRA_UID, ROOT_UID);
419                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
420                 sendCheckPackageResult(remoteCallback, packageName, uid);
421             } else if (Constants.ACTION_GRANT_URI_PERMISSION.equals(action)) {
422                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
423                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
424                         .getString(EXTRA_AUTHORITY);
425                 sendGrantUriPermission(remoteCallback, sourceAuthority, targetPackageName);
426             } else if (Constants.ACTION_REVOKE_URI_PERMISSION.equals(action)) {
427                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
428                         .getString(EXTRA_AUTHORITY);
429                 sendRevokeUriPermission(remoteCallback, sourceAuthority);
430             } else if (Constants.ACTION_AWAIT_PACKAGE_RESTARTED.equals(action)) {
431                 final String packageName = intent.getBundleExtra(EXTRA_DATA).getString(
432                         Intent.EXTRA_PACKAGE_NAME);
433                 awaitPackageRestartedBroadcast(remoteCallback, packageName,
434                         Intent.ACTION_PACKAGE_RESTARTED, TIMEOUT_MS);
435             } else if (Constants.ACTION_GET_CONTENT_PROVIDER_MIME_TYPE.equals(action)) {
436                 final String authority = intent.getBundleExtra(EXTRA_DATA)
437                         .getString(EXTRA_AUTHORITY);
438                 sendGetContentProviderMimeType(remoteCallback, authority);
439             } else if (Constants.ACTION_GET_ENABLED_SPELL_CHECKER_INFOS.equals(action)) {
440                 sendGetEnabledSpellCheckerInfos(remoteCallback);
441             } else if (Constants.ACTION_GET_INPUT_METHOD_LIST.equals(action)) {
442                 sendGetInputMethodList(remoteCallback);
443             } else if (Constants.ACTION_GET_ENABLED_INPUT_METHOD_LIST.equals(action)) {
444                 sendGetEnabledInputMethodList(remoteCallback);
445             } else if (Constants.ACTION_GET_ENABLED_INPUT_METHOD_SUBTYPE_LIST.equals(action)) {
446                 final InputMethodInfo info = intent.getBundleExtra(EXTRA_DATA)
447                         .getParcelable(EXTRA_INPUT_METHOD_INFO, InputMethodInfo.class);
448                 sendGetEnabledInputMethodSubtypeList(remoteCallback, info);
449             } else if (Constants.ACTION_ACCOUNT_MANAGER_GET_AUTHENTICATOR_TYPES.equals(action)) {
450                 sendAccountManagerGetAuthenticatorTypes(remoteCallback);
451             } else if (ACTION_MEDIA_SESSION_MANAGER_IS_TRUSTED_FOR_MEDIA_CONTROL.equals(action)) {
452                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
453                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
454                 sendMediaSessionManagerIsTrustedForMediaControl(remoteCallback, packageName, uid);
455             } else {
456                 sendError(remoteCallback, new Exception("unknown action " + action));
457             }
458         } catch (Exception e) {
459             sendError(remoteCallback, e);
460         }
461     }
462 
sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback)463     private void sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback) {
464         final String[] packages = getSystemService(
465                 AccessibilityManager.class).getInstalledAccessibilityServiceList().stream().map(
466                 p -> p.getComponentName().getPackageName()).distinct().toArray(String[]::new);
467         final Bundle result = new Bundle();
468         result.putStringArray(EXTRA_RETURN_RESULT, packages);
469         remoteCallback.sendResult(result);
470         finish();
471     }
472 
onCommandReady(Intent intent)473     private void onCommandReady(Intent intent) {
474         final RemoteCallback callback = intent.getParcelableExtra(EXTRA_REMOTE_READY_CALLBACK,
475                 RemoteCallback.class);
476         if (callback != null) {
477             callback.sendResult(null);
478         }
479     }
480 
awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName, String action, long timeoutMs)481     private void awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName,
482             String action, long timeoutMs) {
483         final IntentFilter filter = new IntentFilter(action);
484         filter.addDataScheme("package");
485         filter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL);
486         final Object token = new Object();
487         registerReceiver(new BroadcastReceiver() {
488             @Override
489             public void onReceive(Context context, Intent intent) {
490                 final Bundle result = new Bundle();
491                 result.putString(EXTRA_DATA, intent.getDataString());
492                 remoteCallback.sendResult(result);
493                 mainHandler.removeCallbacksAndMessages(token);
494                 finish();
495             }
496         }, filter, Context.RECEIVER_EXPORTED);
497         mainHandler.postDelayed(
498                 () -> sendError(remoteCallback,
499                         new MissingBroadcastException(action, timeoutMs)),
500                 token, timeoutMs);
501     }
502 
awaitPackageRestartedBroadcast(RemoteCallback remoteCallback, String expectedPkgName, String action, long timeoutMs)503     private void awaitPackageRestartedBroadcast(RemoteCallback remoteCallback,
504             String expectedPkgName, String action, long timeoutMs) {
505         final IntentFilter filter = new IntentFilter(action);
506         filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
507         final Object token = new Object();
508         final Bundle result = new Bundle();
509         final Uri expectedData = Uri.fromParts("package", expectedPkgName, null /* fragment */);
510         registerReceiver(new BroadcastReceiver() {
511             @Override
512             public void onReceive(Context context, Intent intent) {
513                 final String intentData = intent.getDataString();
514                 if (expectedData.toString().equals(intentData)) {
515                     mainHandler.removeCallbacksAndMessages(token);
516                     result.putString(Intent.EXTRA_PACKAGE_NAME, expectedPkgName);
517                     remoteCallback.sendResult(result);
518                     finish();
519                 }
520             }
521         }, filter, Context.RECEIVER_EXPORTED);
522         mainHandler.postDelayed(() -> remoteCallback.sendResult(result), token, timeoutMs);
523     }
524 
awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback, List<String> awaitList, String action, long timeoutMs)525     private void awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback,
526             List<String> awaitList, String action, long timeoutMs) {
527         final IntentFilter filter = new IntentFilter(action);
528         final ArrayList<String> suspendedList = new ArrayList<>();
529         final Object token = new Object();
530         final Runnable sendResult = () -> {
531             final Bundle result = new Bundle();
532             result.putStringArray(EXTRA_PACKAGES, suspendedList.toArray(new String[] {}));
533             remoteCallback.sendResult(result);
534             finish();
535         };
536         registerReceiver(new BroadcastReceiver() {
537             @Override
538             public void onReceive(Context context, Intent intent) {
539                 final Bundle extras = intent.getExtras();
540                 final String[] changedList = extras.getStringArray(
541                         Intent.EXTRA_CHANGED_PACKAGE_LIST);
542                 suspendedList.addAll(Arrays.stream(changedList).filter(
543                         p -> awaitList.contains(p)).collect(Collectors.toList()));
544                 if (suspendedList.size() == awaitList.size()) {
545                     mainHandler.removeCallbacksAndMessages(token);
546                     sendResult.run();
547                 }
548             }
549         }, filter, Context.RECEIVER_EXPORTED);
550         mainHandler.postDelayed(() -> sendResult.run(), token, timeoutMs);
551     }
552 
matchPackageNames(String[] expectedPackages, String[] actualPackages)553     private boolean matchPackageNames(String[] expectedPackages, String[] actualPackages) {
554         Arrays.sort(expectedPackages);
555         Arrays.sort(actualPackages);
556         return Arrays.equals(expectedPackages, actualPackages);
557     }
558 
awaitLauncherAppsCallback(RemoteCallback remoteCallback, int expectedEventCode, String[] expectedPackages, long timeoutMs)559     private void awaitLauncherAppsCallback(RemoteCallback remoteCallback, int expectedEventCode,
560             String[] expectedPackages, long timeoutMs) {
561         final Object token = new Object();
562         final Bundle result = new Bundle();
563         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
564         final LauncherApps.Callback launcherAppsCallback = new LauncherApps.Callback() {
565 
566             private void onPackageStateUpdated(String[] packageNames, int resultCode) {
567                 if (resultCode != expectedEventCode) {
568                     return;
569                 }
570                 if (!matchPackageNames(expectedPackages, packageNames)) {
571                     return;
572                 }
573 
574                 mainHandler.removeCallbacksAndMessages(token);
575                 result.putStringArray(EXTRA_PACKAGES, packageNames);
576                 result.putInt(EXTRA_FLAGS, resultCode);
577                 remoteCallback.sendResult(result);
578 
579                 launcherApps.unregisterCallback(this);
580                 finish();
581             }
582 
583             @Override
584             public void onPackageRemoved(String packageName, UserHandle user) {
585                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_REMOVED);
586             }
587 
588             @Override
589             public void onPackageAdded(String packageName, UserHandle user) {
590                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_ADDED);
591             }
592 
593             @Override
594             public void onPackageChanged(String packageName, UserHandle user) {
595                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_CHANGED);
596             }
597 
598             @Override
599             public void onPackagesAvailable(String[] packageNames, UserHandle user,
600                     boolean replacing) {
601                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_AVAILABLE);
602             }
603 
604             @Override
605             public void onPackagesUnavailable(String[] packageNames, UserHandle user,
606                     boolean replacing) {
607                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_UNAVAILABLE);
608             }
609 
610             @Override
611             public void onPackagesSuspended(String[] packageNames, UserHandle user) {
612                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_SUSPENDED);
613                 super.onPackagesSuspended(packageNames, user);
614             }
615 
616             @Override
617             public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
618                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_UNSUSPENDED);
619                 super.onPackagesUnsuspended(packageNames, user);
620             }
621         };
622 
623         launcherApps.registerCallback(launcherAppsCallback);
624 
625         mainHandler.postDelayed(() -> {
626             result.putStringArray(EXTRA_PACKAGES, new String[]{});
627             result.putInt(EXTRA_FLAGS, CALLBACK_EVENT_INVALID);
628             remoteCallback.sendResult(result);
629 
630             launcherApps.unregisterCallback(launcherAppsCallback);
631             finish();
632         }, token, timeoutMs);
633     }
634 
sendGetInstalledPackages(RemoteCallback remoteCallback, int flags)635     private void sendGetInstalledPackages(RemoteCallback remoteCallback, int flags) {
636         String[] packages =
637                 getPackageManager().getInstalledPackages(PackageInfoFlags.of(flags))
638                         .stream().map(p -> p.packageName).distinct().toArray(String[]::new);
639         Bundle result = new Bundle();
640         result.putStringArray(EXTRA_RETURN_RESULT, packages);
641         remoteCallback.sendResult(result);
642         finish();
643     }
644 
sendQueryIntentActivities(RemoteCallback remoteCallback, Intent queryIntent)645     private void sendQueryIntentActivities(RemoteCallback remoteCallback, Intent queryIntent) {
646         final String[] resolveInfos = getPackageManager().queryIntentActivities(
647                 queryIntent, ResolveInfoFlags.of(0)).stream()
648                 .map(ri -> ri.activityInfo.applicationInfo.packageName)
649                 .distinct()
650                 .toArray(String[]::new);
651         Bundle result = new Bundle();
652         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
653         remoteCallback.sendResult(result);
654         finish();
655     }
656 
sendQueryIntentServices(RemoteCallback remoteCallback, Intent queryIntent)657     private void sendQueryIntentServices(RemoteCallback remoteCallback, Intent queryIntent) {
658         final String[] resolveInfos = getPackageManager().queryIntentServices(
659                 queryIntent, ResolveInfoFlags.of(0)).stream()
660                 .map(ri -> ri.serviceInfo.applicationInfo.packageName)
661                 .distinct()
662                 .toArray(String[]::new);
663         Bundle result = new Bundle();
664         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
665         remoteCallback.sendResult(result);
666         finish();
667     }
668 
sendQueryIntentProviders(RemoteCallback remoteCallback, Intent queryIntent)669     private void sendQueryIntentProviders(RemoteCallback remoteCallback, Intent queryIntent) {
670         final String[] resolveInfos = getPackageManager().queryIntentContentProviders(
671                 queryIntent, ResolveInfoFlags.of(0)).stream()
672                 .map(ri -> ri.providerInfo.applicationInfo.packageName)
673                 .distinct()
674                 .toArray(String[]::new);
675         Bundle result = new Bundle();
676         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
677         remoteCallback.sendResult(result);
678         finish();
679     }
680 
queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority)681     private void queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority) {
682         backgroundHandler.post(() -> {
683             Uri queryUri = Uri.parse("content://" + authority + "/test");
684             Cursor query = getContentResolver().query(queryUri, null, null, null, null);
685             if (query == null || !query.moveToFirst()) {
686                 sendError(remoteCallback,
687                         new IllegalStateException(
688                                 "Query of " + queryUri + " could not be completed"));
689                 return;
690             }
691             ArrayList<String> visiblePackages = new ArrayList<>();
692             while (!query.isAfterLast()) {
693                 visiblePackages.add(query.getString(0));
694                 query.moveToNext();
695             }
696             query.close();
697 
698             mainHandler.post(() -> {
699                 Bundle result = new Bundle();
700                 result.putStringArray(EXTRA_RETURN_RESULT, visiblePackages.toArray(new String[]{}));
701                 remoteCallback.sendResult(result);
702                 finish();
703             });
704 
705         });
706     }
707 
sendError(RemoteCallback remoteCallback, Exception failure)708     private void sendError(RemoteCallback remoteCallback, Exception failure) {
709         Bundle result = new Bundle();
710         result.putSerializable(EXTRA_ERROR, failure);
711         if (remoteCallback != null) {
712             remoteCallback.sendResult(result);
713         }
714         finish();
715     }
716 
sendPackageInfo(RemoteCallback remoteCallback, String packageName)717     private void sendPackageInfo(RemoteCallback remoteCallback, String packageName) {
718         final PackageInfo pi;
719         try {
720             pi = getPackageManager().getPackageInfo(packageName, PackageInfoFlags.of(0));
721         } catch (PackageManager.NameNotFoundException e) {
722             sendError(remoteCallback, e);
723             return;
724         }
725         Bundle result = new Bundle();
726         result.putParcelable(EXTRA_RETURN_RESULT, pi);
727         remoteCallback.sendResult(result);
728         finish();
729     }
730 
sendPackagesForUid(RemoteCallback remoteCallback, int uid)731     private void sendPackagesForUid(RemoteCallback remoteCallback, int uid) {
732         final String[] packages = getPackageManager().getPackagesForUid(uid);
733         final Bundle result = new Bundle();
734         result.putStringArray(EXTRA_RETURN_RESULT, packages);
735         remoteCallback.sendResult(result);
736         finish();
737     }
738 
sendNameForUid(RemoteCallback remoteCallback, int uid)739     private void sendNameForUid(RemoteCallback remoteCallback, int uid) {
740         final String name = getPackageManager().getNameForUid(uid);
741         final Bundle result = new Bundle();
742         result.putString(EXTRA_RETURN_RESULT, name);
743         remoteCallback.sendResult(result);
744         finish();
745     }
746 
sendNamesForUids(RemoteCallback remoteCallback, int uid)747     private void sendNamesForUids(RemoteCallback remoteCallback, int uid) {
748         final String[] names = getPackageManager().getNamesForUids(new int[]{uid});
749         final Bundle result = new Bundle();
750         result.putStringArray(EXTRA_RETURN_RESULT, names);
751         remoteCallback.sendResult(result);
752         finish();
753     }
754 
sendCheckSignatures(RemoteCallback remoteCallback, int uid1, int uid2)755     private void sendCheckSignatures(RemoteCallback remoteCallback, int uid1, int uid2) {
756         final int signatureResult = getPackageManager().checkSignatures(uid1, uid2);
757         final Bundle result = new Bundle();
758         result.putInt(EXTRA_RETURN_RESULT, signatureResult);
759         remoteCallback.sendResult(result);
760         finish();
761     }
762 
sendHasSigningCertificate(RemoteCallback remoteCallback, int uid, byte[] cert, int type)763     private void sendHasSigningCertificate(RemoteCallback remoteCallback, int uid, byte[] cert,
764             int type) {
765         final boolean signatureResult = getPackageManager().hasSigningCertificate(uid, cert, type);
766         final Bundle result = new Bundle();
767         result.putBoolean(EXTRA_RETURN_RESULT, signatureResult);
768         remoteCallback.sendResult(result);
769         finish();
770     }
771 
772     /**
773      * Instead of sending a list of package names, this function sends a List of
774      * {@link SyncAdapterType}, since the {@link SyncAdapterType#getPackageName()} is a test api
775      * which can only be invoked in the instrumentation.
776      */
sendSyncAdapterTypes(RemoteCallback remoteCallback)777     private void sendSyncAdapterTypes(RemoteCallback remoteCallback) {
778         final SyncAdapterType[] types = ContentResolver.getSyncAdapterTypes();
779         final ArrayList<Parcelable> parcelables = new ArrayList<>();
780         for (SyncAdapterType type : types) {
781             parcelables.add(type);
782         }
783         final Bundle result = new Bundle();
784         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
785         remoteCallback.sendResult(result);
786         finish();
787     }
788 
sendIsActivityEnabled(RemoteCallback remoteCallback, ComponentName componentName)789     private void sendIsActivityEnabled(RemoteCallback remoteCallback, ComponentName componentName) {
790         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
791         final Bundle result = new Bundle();
792         try {
793             result.putBoolean(EXTRA_RETURN_RESULT, launcherApps.isActivityEnabled(componentName,
794                     Process.myUserHandle()));
795         } catch (IllegalArgumentException e) {
796         }
797         remoteCallback.sendResult(result);
798         finish();
799     }
800 
sendGetSuspendedPackageLauncherExtras(RemoteCallback remoteCallback, String packageName)801     private void sendGetSuspendedPackageLauncherExtras(RemoteCallback remoteCallback,
802             String packageName) {
803         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
804         final Bundle result = new Bundle();
805         try {
806             result.putBundle(EXTRA_RETURN_RESULT,
807                     launcherApps.getSuspendedPackageLauncherExtras(packageName,
808                             Process.myUserHandle()));
809         } catch (IllegalArgumentException e) {
810         }
811         remoteCallback.sendResult(result);
812         finish();
813     }
814 
sendInstalledAppWidgetProviders(RemoteCallback remoteCallback)815     private void sendInstalledAppWidgetProviders(RemoteCallback remoteCallback) {
816         final AppWidgetManager appWidgetManager = getSystemService(AppWidgetManager.class);
817         final List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
818         final ArrayList<Parcelable> parcelables = new ArrayList<>();
819         final int segmentSize = 10;
820 
821         // Sends in one parcelable array directly if the size of providers is
822         // less than segmentSize, then early-exits.
823         if (providers.size() <= segmentSize) {
824             parcelables.addAll(providers);
825             final Bundle result = new Bundle();
826             result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
827             remoteCallback.sendResult(result);
828             finish();
829         }
830 
831         // In order to avoid RemoteCallback receiving a large amount of data at one time,
832         // we transmit 10 items at a time.
833         for (AppWidgetProviderInfo info : providers) {
834             parcelables.add(info);
835             if (parcelables.size() == segmentSize) {
836                 sendSegmentAppWidgetProviders(remoteCallback, parcelables,
837                         (short) providers.size());
838                 parcelables.clear();
839             }
840         }
841         // When the size of providers is less than segmentSize (E.g. 8 < 10) or
842         // the size % segmentSize is not zero (E.g. 56 % 10 = 6), send the result
843         // to complete it.
844         if (parcelables.size() > 0) {
845             sendSegmentAppWidgetProviders(remoteCallback, parcelables, (short) providers.size());
846         }
847         finish();
848     }
849 
sendSegmentAppWidgetProviders(RemoteCallback remoteCallback, List<Parcelable> parcelables, short providerSize)850     private void sendSegmentAppWidgetProviders(RemoteCallback remoteCallback,
851             List<Parcelable> parcelables, short providerSize) {
852         final Bundle result = new Bundle();
853         final ArrayList<Parcelable> segment = new ArrayList<>(parcelables);
854         result.putParcelableArrayList(EXTRA_SEGMENT_RESULT, segment);
855         // Transmit total size of the AppWidgetProviderInfo list,
856         // so RemoteCallback knows when to stop receiving.
857         result.putShort(EXTRA_SEGMENT_SIZE, providerSize);
858         remoteCallback.sendResult(result);
859     }
860 
sendSyncAdapterPackagesForAuthorityAsUser(RemoteCallback remoteCallback, String authority, int userId)861     private void sendSyncAdapterPackagesForAuthorityAsUser(RemoteCallback remoteCallback,
862             String authority, int userId) {
863         final String[] syncAdapterPackages = ContentResolver
864                 .getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
865         final Bundle result = new Bundle();
866         result.putStringArray(Intent.EXTRA_PACKAGES, syncAdapterPackages);
867         remoteCallback.sendResult(result);
868         finish();
869     }
870 
awaitRequestSyncStatus(RemoteCallback remoteCallback, String action, Account account, String authority, long timeoutMs)871     private void awaitRequestSyncStatus(RemoteCallback remoteCallback, String action,
872             Account account, String authority, long timeoutMs) {
873         ContentResolver.cancelSync(account, authority);
874         final Object token = new Object();
875         final SyncStatusObserver observer = which -> {
876             final Bundle result = new Bundle();
877             result.putBoolean(EXTRA_RETURN_RESULT, true);
878             remoteCallback.sendResult(result);
879             mainHandler.removeCallbacksAndMessages(token);
880             finish();
881         };
882         syncStatusHandle = ContentResolver.addStatusChangeListener(
883                 ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
884                         | ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS
885                         | ContentResolver.SYNC_OBSERVER_TYPE_PENDING, observer);
886 
887         ContentResolver.requestSync(account, authority, new Bundle());
888         mainHandler.postDelayed(
889                 () -> sendError(remoteCallback, new MissingCallbackException(action, timeoutMs)),
890                 token, timeoutMs);
891     }
892 
sendGetSyncAdapterControlPanel(RemoteCallback remoteCallback, Account account, String authority, ComponentName componentName)893     private void sendGetSyncAdapterControlPanel(RemoteCallback remoteCallback, Account account,
894             String authority, ComponentName componentName) {
895         ContentResolver.cancelSync(account, authority);
896         ContentResolver.requestSync(account, authority, new Bundle());
897         final ActivityManager activityManager = getSystemService(ActivityManager.class);
898         final PendingIntent pendingIntent =
899                 activityManager.getRunningServiceControlPanel(componentName);
900         final Bundle result = new Bundle();
901         result.putParcelable(EXTRA_RETURN_RESULT, pendingIntent);
902         remoteCallback.sendResult(result);
903         finish();
904     }
905 
awaitRequestPeriodicSync(RemoteCallback remoteCallback, Account account, String authority, long timeoutMs)906     private void awaitRequestPeriodicSync(RemoteCallback remoteCallback, Account account,
907             String authority, long timeoutMs) {
908         ContentResolver.addPeriodicSync(account, authority, Bundle.EMPTY,
909                 TimeUnit.HOURS.toSeconds(1));
910         final Object token = new Object();
911         final Bundle result = new Bundle();
912         final Runnable pollingPeriodicSync = new Runnable() {
913             @Override
914             public void run() {
915                 if (!ContentResolver.getPeriodicSyncs(account, authority).stream()
916                         .anyMatch(sync -> sync.authority.equals(authority))) {
917                     mainHandler.postDelayed(this, 100 /* delayMillis */);
918                     return;
919                 }
920                 mainHandler.removeCallbacksAndMessages(token);
921                 result.putBoolean(EXTRA_RETURN_RESULT, true);
922                 remoteCallback.sendResult(result);
923                 finish();
924             }
925         };
926 
927         mainHandler.post(pollingPeriodicSync);
928         mainHandler.postDelayed(() -> {
929             mainHandler.removeCallbacks(pollingPeriodicSync);
930             result.putBoolean(EXTRA_RETURN_RESULT, false);
931             remoteCallback.sendResult(result);
932             finish();
933         }, token, timeoutMs);
934     }
935 
setSyncAutomatically(RemoteCallback remoteCallback, Account account, String authority)936     private void setSyncAutomatically(RemoteCallback remoteCallback, Account account,
937             String authority) {
938         ContentResolver.setSyncAutomatically(account, authority, true /* sync */);
939         remoteCallback.sendResult(null);
940         finish();
941     }
942 
getSyncAutomatically(RemoteCallback remoteCallback, String authority)943     private void getSyncAutomatically(RemoteCallback remoteCallback, String authority) {
944         final boolean ret = ContentResolver.getSyncAutomatically(null /* account */, authority);
945         final Bundle result = new Bundle();
946         result.putBoolean(EXTRA_RETURN_RESULT, ret);
947         remoteCallback.sendResult(result);
948         finish();
949     }
950 
getIsSyncable(RemoteCallback remoteCallback, Account account, String authority)951     private void getIsSyncable(RemoteCallback remoteCallback, Account account,
952             String authority) {
953         final int ret = ContentResolver.getIsSyncable(account, authority);
954         final Bundle result = new Bundle();
955         result.putInt(EXTRA_RETURN_RESULT, ret);
956         remoteCallback.sendResult(result);
957         finish();
958     }
959 
getPeriodicSyncs(RemoteCallback remoteCallback, Account account, String authority)960     private void getPeriodicSyncs(RemoteCallback remoteCallback, Account account,
961             String authority) {
962         final List<PeriodicSync> periodicSyncList =
963                 ContentResolver.getPeriodicSyncs(account, authority);
964         final ArrayList<Parcelable> parcelables = new ArrayList<>();
965         for (PeriodicSync sync : periodicSyncList) {
966             parcelables.add(sync);
967         }
968         final Bundle result = new Bundle();
969         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
970         remoteCallback.sendResult(result);
971         finish();
972     }
973 
sendGetSharedLibraryDependentPackages(RemoteCallback remoteCallback, String sharedLibName)974     private void sendGetSharedLibraryDependentPackages(RemoteCallback remoteCallback,
975             String sharedLibName) {
976         final List<SharedLibraryInfo> sharedLibraryInfos = getPackageManager()
977                 .getSharedLibraries(0 /* flags */);
978         SharedLibraryInfo sharedLibraryInfo = sharedLibraryInfos.stream().filter(
979                 info -> sharedLibName.equals(info.getName())).findAny().orElse(null);
980         final String[] dependentPackages = sharedLibraryInfo == null ? null
981                 : sharedLibraryInfo.getDependentPackages().stream()
982                         .map(versionedPackage -> versionedPackage.getPackageName())
983                         .distinct().collect(Collectors.toList()).toArray(new String[]{});
984         final Bundle result = new Bundle();
985         result.putStringArray(Intent.EXTRA_PACKAGES, dependentPackages);
986         remoteCallback.sendResult(result);
987         finish();
988     }
989 
sendGetPreferredActivities(RemoteCallback remoteCallback)990     private void sendGetPreferredActivities(RemoteCallback remoteCallback) {
991         final List<IntentFilter> filters = new ArrayList<>();
992         final List<ComponentName> activities = new ArrayList<>();
993         getPackageManager().getPreferredActivities(filters, activities, null /* packageName*/);
994         final String[] packages = activities.stream()
995                 .map(componentName -> componentName.getPackageName()).distinct()
996                 .collect(Collectors.toList()).toArray(new String[]{});
997         final Bundle result = new Bundle();
998         result.putStringArray(Intent.EXTRA_PACKAGES, packages);
999         remoteCallback.sendResult(result);
1000         finish();
1001     }
1002 
sendSetInstallerPackageName(RemoteCallback remoteCallback, String targetPackageName, String installerPackageName)1003     private void sendSetInstallerPackageName(RemoteCallback remoteCallback,
1004             String targetPackageName, String installerPackageName) {
1005         try {
1006             getPackageManager().setInstallerPackageName(targetPackageName, installerPackageName);
1007             remoteCallback.sendResult(null);
1008             finish();
1009         } catch (Exception e) {
1010             sendError(remoteCallback, e);
1011         }
1012     }
1013 
sendLauncherAppsShouldHideFromSuggestions(RemoteCallback remoteCallback, String targetPackageName, int userId)1014     private void sendLauncherAppsShouldHideFromSuggestions(RemoteCallback remoteCallback,
1015             String targetPackageName, int userId) {
1016         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
1017         final boolean hideFromSuggestions = launcherApps.shouldHideFromSuggestions(
1018                 targetPackageName, UserHandle.of(userId));
1019         final Bundle result = new Bundle();
1020         result.putBoolean(EXTRA_RETURN_RESULT, hideFromSuggestions);
1021         remoteCallback.sendResult(result);
1022         finish();
1023     }
1024 
sendCheckUriPermission(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName, int targetUid)1025     private void sendCheckUriPermission(RemoteCallback remoteCallback, String sourceAuthority,
1026             String targetPackageName, int targetUid) {
1027         Uri uri = getContentUriAndGrantRead(sourceAuthority, targetPackageName);
1028         final int permissionResult = checkUriPermission(uri, 0 /* pid */, targetUid,
1029                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
1030         revokeReadFromUriAndSendPermissionResult(uri, permissionResult, remoteCallback);
1031     }
1032 
sendCheckContentUriPermissionFull(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName, int targetUid)1033     private void sendCheckContentUriPermissionFull(RemoteCallback remoteCallback,
1034             String sourceAuthority, String targetPackageName, int targetUid) {
1035         Uri uri = getContentUriAndGrantRead(sourceAuthority, targetPackageName);
1036         final int permissionResult = checkContentUriPermissionFull(uri, 0 /* pid */, targetUid,
1037                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
1038         revokeReadFromUriAndSendPermissionResult(uri, permissionResult, remoteCallback);
1039     }
1040 
getContentUriAndGrantRead(String sourceAuthority, String targetPackageName)1041     private Uri getContentUriAndGrantRead(String sourceAuthority, String targetPackageName) {
1042         final Uri uri = Uri.parse("content://" + sourceAuthority);
1043         grantUriPermission(targetPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1044         return uri;
1045     }
1046 
revokeReadFromUriAndSendPermissionResult(Uri uri, int permissionResult, RemoteCallback remoteCallback)1047     private void revokeReadFromUriAndSendPermissionResult(Uri uri, int permissionResult,
1048             RemoteCallback remoteCallback) {
1049         revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1050         final Bundle result = new Bundle();
1051         result.putInt(EXTRA_RETURN_RESULT, permissionResult);
1052         remoteCallback.sendResult(result);
1053         finish();
1054     }
1055 
sendGrantUriPermission(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName)1056     private void sendGrantUriPermission(RemoteCallback remoteCallback, String sourceAuthority,
1057             String targetPackageName) {
1058         final Uri uri = Uri.parse("content://" + sourceAuthority);
1059         grantUriPermission(targetPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1060         remoteCallback.sendResult(null);
1061         finish();
1062     }
1063 
sendRevokeUriPermission(RemoteCallback remoteCallback, String sourceAuthority)1064     private void sendRevokeUriPermission(RemoteCallback remoteCallback, String sourceAuthority) {
1065         final Uri uri = Uri.parse("content://" + sourceAuthority);
1066         revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1067         remoteCallback.sendResult(null);
1068         finish();
1069     }
1070 
sendCanPackageQuery(RemoteCallback remoteCallback, String sourcePackageName, String targetPackageName)1071     private void sendCanPackageQuery(RemoteCallback remoteCallback, String sourcePackageName,
1072             String targetPackageName) {
1073         try {
1074             final boolean visibility = getPackageManager().canPackageQuery(sourcePackageName,
1075                     targetPackageName);
1076             final Bundle result = new Bundle();
1077             result.putBoolean(EXTRA_RETURN_RESULT, visibility);
1078             remoteCallback.sendResult(result);
1079             finish();
1080         } catch (PackageManager.NameNotFoundException e) {
1081             sendError(remoteCallback, e);
1082         }
1083     }
1084 
sendCanPackageQueries(RemoteCallback remoteCallback, String sourcePackageName, String[] targetPackageNames)1085     private void sendCanPackageQueries(RemoteCallback remoteCallback, String sourcePackageName,
1086             String[] targetPackageNames) {
1087         try {
1088             final boolean[] visibilities = getPackageManager().canPackageQuery(sourcePackageName,
1089                     targetPackageNames);
1090             final Bundle result = new Bundle();
1091             result.putBooleanArray(EXTRA_RETURN_RESULT, visibilities);
1092             remoteCallback.sendResult(result);
1093             finish();
1094         } catch (PackageManager.NameNotFoundException e) {
1095             sendError(remoteCallback, e);
1096         }
1097     }
1098 
sendSessionInfosListResult(RemoteCallback remoteCallback, List<SessionInfo> infos)1099     private void sendSessionInfosListResult(RemoteCallback remoteCallback,
1100             List<SessionInfo> infos) {
1101         final ArrayList<Parcelable> parcelables = new ArrayList<>(infos);
1102         for (SessionInfo info : infos) {
1103             parcelables.add(info);
1104         }
1105         final Bundle result = new Bundle();
1106         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
1107         remoteCallback.sendResult(result);
1108         finish();
1109     }
1110 
sendGetContentProviderMimeType(RemoteCallback remoteCallback, String authority)1111     private void sendGetContentProviderMimeType(RemoteCallback remoteCallback, String authority) {
1112         final Uri uri = Uri.parse("content://" + authority);
1113         final ContentResolver resolver = getContentResolver();
1114         final String mimeType = resolver.getType(uri);
1115         final Bundle result = new Bundle();
1116         result.putString(EXTRA_RETURN_RESULT, mimeType);
1117         remoteCallback.sendResult(result);
1118         finish();
1119     }
1120 
awaitLauncherAppsSessionCallback(RemoteCallback remoteCallback, int expectedSessionId, long timeoutMs)1121     private void awaitLauncherAppsSessionCallback(RemoteCallback remoteCallback,
1122             int expectedSessionId, long timeoutMs) {
1123         final Object token = new Object();
1124         final Bundle result = new Bundle();
1125         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
1126         final SessionCallback sessionCallback = new SessionCallback() {
1127 
1128             @Override
1129             public void onCreated(int sessionId) {
1130                 // No-op
1131             }
1132 
1133             @Override
1134             public void onBadgingChanged(int sessionId) {
1135                 // No-op
1136             }
1137 
1138             @Override
1139             public void onActiveChanged(int sessionId, boolean active) {
1140                 // No-op
1141             }
1142 
1143             @Override
1144             public void onProgressChanged(int sessionId, float progress) {
1145                 // No-op
1146             }
1147 
1148             @Override
1149             public void onFinished(int sessionId, boolean success) {
1150                 if (sessionId != expectedSessionId) {
1151                     return;
1152                 }
1153 
1154                 mainHandler.removeCallbacksAndMessages(token);
1155                 result.putInt(EXTRA_ID, sessionId);
1156                 remoteCallback.sendResult(result);
1157 
1158                 launcherApps.unregisterPackageInstallerSessionCallback(this);
1159                 finish();
1160             }
1161         };
1162 
1163         launcherApps.registerPackageInstallerSessionCallback(this.getMainExecutor(),
1164                 sessionCallback);
1165 
1166         mainHandler.postDelayed(() -> {
1167             result.putInt(EXTRA_ID, SessionInfo.INVALID_ID);
1168             remoteCallback.sendResult(result);
1169 
1170             launcherApps.unregisterPackageInstallerSessionCallback(sessionCallback);
1171             finish();
1172         }, token, timeoutMs);
1173     }
1174 
sendPendingIntentGetActivity(RemoteCallback remoteCallback)1175     private void sendPendingIntentGetActivity(RemoteCallback remoteCallback) {
1176         final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* requestCode */,
1177                 new Intent(this, TestActivity.class), PendingIntent.FLAG_IMMUTABLE);
1178         final Bundle result = new Bundle();
1179         result.putParcelable(EXTRA_PENDING_INTENT, pendingIntent);
1180         remoteCallback.sendResult(result);
1181         finish();
1182     }
1183 
sendPendingIntentGetCreatorPackage(RemoteCallback remoteCallback, PendingIntent pendingIntent)1184     private void sendPendingIntentGetCreatorPackage(RemoteCallback remoteCallback,
1185             PendingIntent pendingIntent) {
1186         final Bundle result = new Bundle();
1187         result.putString(Intent.EXTRA_PACKAGE_NAME, pendingIntent.getCreatorPackage());
1188         remoteCallback.sendResult(result);
1189         finish();
1190     }
1191 
sendCheckPackageResult(RemoteCallback remoteCallback, String packageName, int uid)1192     private void sendCheckPackageResult(RemoteCallback remoteCallback, String packageName,
1193             int uid) {
1194         try {
1195             getSystemService(AppOpsManager.class).checkPackage(uid, packageName);
1196             final Bundle result = new Bundle();
1197             result.putBoolean(EXTRA_RETURN_RESULT, true);
1198             remoteCallback.sendResult(result);
1199             finish();
1200         } catch (SecurityException e) {
1201             sendError(remoteCallback, e);
1202         }
1203     }
1204 
sendGetEnabledSpellCheckerInfos(RemoteCallback remoteCallback)1205     private void sendGetEnabledSpellCheckerInfos(RemoteCallback remoteCallback) {
1206         final TextServicesManager tsm = getSystemService(TextServicesManager.class);
1207         final ArrayList<SpellCheckerInfo> infos =
1208                 new ArrayList<>(tsm.getEnabledSpellCheckerInfos());
1209         final Bundle result = new Bundle();
1210         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1211         remoteCallback.sendResult(result);
1212         finish();
1213     }
1214 
sendGetInputMethodList(RemoteCallback remoteCallback)1215     private void sendGetInputMethodList(RemoteCallback remoteCallback) {
1216         final InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
1217         final ArrayList<InputMethodInfo> infos =
1218                 new ArrayList<>(inputMethodManager.getInputMethodList());
1219         final Bundle result = new Bundle();
1220         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1221         remoteCallback.sendResult(result);
1222         finish();
1223     }
1224 
sendGetEnabledInputMethodList(RemoteCallback remoteCallback)1225     private void sendGetEnabledInputMethodList(RemoteCallback remoteCallback) {
1226         final InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
1227         final ArrayList<InputMethodInfo> infos =
1228                 new ArrayList<>(inputMethodManager.getEnabledInputMethodList());
1229         final Bundle result = new Bundle();
1230         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1231         remoteCallback.sendResult(result);
1232         finish();
1233     }
1234 
sendGetEnabledInputMethodSubtypeList(RemoteCallback remoteCallback, InputMethodInfo targetImi)1235     private void sendGetEnabledInputMethodSubtypeList(RemoteCallback remoteCallback,
1236             InputMethodInfo targetImi) {
1237         final InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
1238         final ArrayList<InputMethodSubtype> infos = new ArrayList<>(
1239                 inputMethodManager.getEnabledInputMethodSubtypeList(targetImi, true));
1240         final Bundle result = new Bundle();
1241         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1242         remoteCallback.sendResult(result);
1243         finish();
1244     }
1245 
sendAccountManagerGetAuthenticatorTypes(RemoteCallback remoteCallback)1246     private void sendAccountManagerGetAuthenticatorTypes(RemoteCallback remoteCallback) {
1247         final AccountManager accountManager = AccountManager.get(this);
1248         final Bundle result = new Bundle();
1249         result.putParcelableArray(EXTRA_RETURN_RESULT, accountManager.getAuthenticatorTypes());
1250         remoteCallback.sendResult(result);
1251         finish();
1252     }
1253 
sendMediaSessionManagerIsTrustedForMediaControl(RemoteCallback remoteCallback, String packageName, int uid)1254     private void sendMediaSessionManagerIsTrustedForMediaControl(RemoteCallback remoteCallback,
1255             String packageName, int uid) {
1256         final MediaSessionManager mediaSessionManager =
1257                 getSystemService(MediaSessionManager.class);
1258         final MediaSessionManager.RemoteUserInfo userInfo =
1259                 new MediaSessionManager.RemoteUserInfo(packageName, 0 /* pid */, uid);
1260         final boolean isTrusted = mediaSessionManager.isTrustedForMediaControl(userInfo);
1261         final Bundle result = new Bundle();
1262         result.putBoolean(EXTRA_RETURN_RESULT, isTrusted);
1263         remoteCallback.sendResult(result);
1264         finish();
1265     }
1266 
1267     @Override
onActivityResult(int requestCode, int resultCode, Intent data)1268     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1269         super.onActivityResult(requestCode, resultCode, data);
1270         final RemoteCallback remoteCallback = callbacks.get(requestCode);
1271         if (resultCode != RESULT_OK) {
1272             final Exception e = data.getSerializableExtra(EXTRA_ERROR, Exception.class);
1273             sendError(remoteCallback, e == null ? new Exception("Result was " + resultCode) : e);
1274             return;
1275         }
1276         final Bundle result = new Bundle();
1277         result.putParcelable(EXTRA_RETURN_RESULT, data.getParcelableExtra(EXTRA_RETURN_RESULT));
1278         remoteCallback.sendResult(result);
1279         finish();
1280     }
1281 
bindService(RemoteCallback remoteCallback, String packageName)1282     private void bindService(RemoteCallback remoteCallback, String packageName) {
1283         final Intent intent = new Intent(ACTION_MANIFEST_SERVICE);
1284         intent.setClassName(packageName, SERVICE_CLASS_DUMMY_SERVICE);
1285         final ServiceConnection serviceConnection = new ServiceConnection() {
1286             @Override
1287             public void onServiceConnected(ComponentName className, IBinder service) {
1288                 // No-op
1289             }
1290 
1291             @Override
1292             public void onServiceDisconnected(ComponentName className) {
1293                 // No-op
1294             }
1295 
1296             @Override
1297             public void onBindingDied(ComponentName name) {
1298                 // Remote service die
1299                 finish();
1300             }
1301 
1302             @Override
1303             public void onNullBinding(ComponentName name) {
1304                 // Since the DummyService doesn't implement onBind, it returns null and
1305                 // onNullBinding would be called. Use postDelayed to keep this service
1306                 // connection alive for 3 seconds.
1307                 mainHandler.postDelayed(() -> {
1308                     unbindService(this);
1309                     finish();
1310                 }, TIMEOUT_MS);
1311             }
1312         };
1313 
1314         final boolean bound = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
1315         final Bundle result = new Bundle();
1316         result.putBoolean(EXTRA_RETURN_RESULT, bound);
1317         remoteCallback.sendResult(result);
1318         // Don't invoke finish() right here if service is bound successfully to keep the service
1319         // connection alive since the ServiceRecord would be removed from the ServiceMap once no
1320         // client is binding the service.
1321         if (!bound) finish();
1322     }
1323 }
1324