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