• 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 = 7000;
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_CHECK_CONTENT_URI_PERMISSION_FULL.equals(action)) {
360                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
361                 final int targetUid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
362                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
363                         .getString(EXTRA_AUTHORITY);
364                 sendCheckContentUriPermissionFull(remoteCallback, sourceAuthority,
365                         targetPackageName, targetUid);
366             } else if (Constants.ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
367                 final Uri uri = intent.getData();
368                 final int modeFlags = intent.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION
369                         | Intent.FLAG_GRANT_READ_URI_PERMISSION);
370                 if (uri != null) {
371                     getContentResolver().takePersistableUriPermission(uri, modeFlags);
372                 }
373                 finish();
374             } else if (Constants.ACTION_CAN_PACKAGE_QUERY.equals(action)) {
375                 final String sourcePackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
376                 final String targetPackageName = intent.getBundleExtra(EXTRA_DATA)
377                         .getString(Intent.EXTRA_PACKAGE_NAME);
378                 sendCanPackageQuery(remoteCallback, sourcePackageName, targetPackageName);
379             } else if (Constants.ACTION_CAN_PACKAGE_QUERIES.equals(action)) {
380                 final String sourcePackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
381                 final String[] targetPackageNames = intent.getBundleExtra(EXTRA_DATA)
382                         .getStringArray(EXTRA_PACKAGES);
383                 sendCanPackageQueries(remoteCallback, sourcePackageName, targetPackageNames);
384             } else if (Constants.ACTION_GET_ALL_PACKAGE_INSTALLER_SESSIONS.equals(action)) {
385                 final List<SessionInfo> infos = getSystemService(LauncherApps.class)
386                         .getAllPackageInstallerSessions();
387                 sendSessionInfosListResult(remoteCallback, infos);
388             } else if (Constants.ACTION_AWAIT_LAUNCHER_APPS_SESSION_CALLBACK.equals(action)) {
389                 final int expectedEventCode = intent.getBundleExtra(EXTRA_DATA)
390                         .getInt(EXTRA_ID, SessionInfo.INVALID_ID);
391                 awaitLauncherAppsSessionCallback(remoteCallback, expectedEventCode,
392                         EXTENDED_TIMEOUT_MS);
393             } else if (Constants.ACTION_GET_SESSION_INFO.equals(action)) {
394                 final int sessionId = intent.getBundleExtra(EXTRA_DATA)
395                         .getInt(EXTRA_ID, SessionInfo.INVALID_ID);
396                 final List<SessionInfo> infos = Arrays.asList(getPackageManager()
397                         .getPackageInstaller()
398                         .getSessionInfo(sessionId));
399                 sendSessionInfosListResult(remoteCallback, infos);
400             } else if (Constants.ACTION_GET_STAGED_SESSIONS.equals(action)) {
401                 final List<SessionInfo> infos = getPackageManager().getPackageInstaller()
402                         .getStagedSessions();
403                 sendSessionInfosListResult(remoteCallback, infos);
404             } else if (Constants.ACTION_GET_ALL_SESSIONS.equals(action)) {
405                 final List<SessionInfo> infos = getPackageManager().getPackageInstaller()
406                         .getAllSessions();
407                 sendSessionInfosListResult(remoteCallback, infos);
408             } else if (Constants.ACTION_PENDING_INTENT_GET_ACTIVITY.equals(action)) {
409                 sendPendingIntentGetActivity(remoteCallback);
410             } else if (Constants.ACTION_PENDING_INTENT_GET_CREATOR_PACKAGE.equals(action)) {
411                 sendPendingIntentGetCreatorPackage(remoteCallback,
412                         intent.getParcelableExtra(EXTRA_PENDING_INTENT, PendingIntent.class));
413             } else if (Constants.ACTION_CHECK_PACKAGE.equals(action)) {
414                 // Using ROOT_UID as default value here to pass the check in #verifyAndGetBypass,
415                 // this is intended by design.
416                 final int uid = intent.getIntExtra(EXTRA_UID, ROOT_UID);
417                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
418                 sendCheckPackageResult(remoteCallback, packageName, uid);
419             } else if (Constants.ACTION_GRANT_URI_PERMISSION.equals(action)) {
420                 final String targetPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
421                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
422                         .getString(EXTRA_AUTHORITY);
423                 sendGrantUriPermission(remoteCallback, sourceAuthority, targetPackageName);
424             } else if (Constants.ACTION_REVOKE_URI_PERMISSION.equals(action)) {
425                 final String sourceAuthority = intent.getBundleExtra(EXTRA_DATA)
426                         .getString(EXTRA_AUTHORITY);
427                 sendRevokeUriPermission(remoteCallback, sourceAuthority);
428             } else if (Constants.ACTION_AWAIT_PACKAGE_RESTARTED.equals(action)) {
429                 final String packageName = intent.getBundleExtra(EXTRA_DATA).getString(
430                         Intent.EXTRA_PACKAGE_NAME);
431                 awaitPackageRestartedBroadcast(remoteCallback, packageName,
432                         Intent.ACTION_PACKAGE_RESTARTED, TIMEOUT_MS);
433             } else if (Constants.ACTION_GET_CONTENT_PROVIDER_MIME_TYPE.equals(action)) {
434                 final String authority = intent.getBundleExtra(EXTRA_DATA)
435                         .getString(EXTRA_AUTHORITY);
436                 sendGetContentProviderMimeType(remoteCallback, authority);
437             } else if (Constants.ACTION_GET_ENABLED_SPELL_CHECKER_INFOS.equals(action)) {
438                 sendGetEnabledSpellCheckerInfos(remoteCallback);
439             } else if (Constants.ACTION_GET_INPUT_METHOD_LIST.equals(action)) {
440                 sendGetInputMethodList(remoteCallback);
441             } else if (Constants.ACTION_GET_ENABLED_INPUT_METHOD_LIST.equals(action)) {
442                 sendGetEnabledInputMethodList(remoteCallback);
443             } else if (Constants.ACTION_GET_ENABLED_INPUT_METHOD_SUBTYPE_LIST.equals(action)) {
444                 final InputMethodInfo info = intent.getBundleExtra(EXTRA_DATA)
445                         .getParcelable(EXTRA_INPUT_METHOD_INFO, InputMethodInfo.class);
446                 sendGetEnabledInputMethodSubtypeList(remoteCallback, info);
447             } else if (Constants.ACTION_ACCOUNT_MANAGER_GET_AUTHENTICATOR_TYPES.equals(action)) {
448                 sendAccountManagerGetAuthenticatorTypes(remoteCallback);
449             } else if (ACTION_MEDIA_SESSION_MANAGER_IS_TRUSTED_FOR_MEDIA_CONTROL.equals(action)) {
450                 final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
451                 final int uid = intent.getIntExtra(EXTRA_UID, INVALID_UID);
452                 sendMediaSessionManagerIsTrustedForMediaControl(remoteCallback, packageName, uid);
453             } else {
454                 sendError(remoteCallback, new Exception("unknown action " + action));
455             }
456         } catch (Exception e) {
457             sendError(remoteCallback, e);
458         }
459     }
460 
sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback)461     private void sendGetInstalledAccessibilityServicePackages(RemoteCallback remoteCallback) {
462         final String[] packages = getSystemService(
463                 AccessibilityManager.class).getInstalledAccessibilityServiceList().stream().map(
464                 p -> p.getComponentName().getPackageName()).distinct().toArray(String[]::new);
465         final Bundle result = new Bundle();
466         result.putStringArray(EXTRA_RETURN_RESULT, packages);
467         remoteCallback.sendResult(result);
468         finish();
469     }
470 
onCommandReady(Intent intent)471     private void onCommandReady(Intent intent) {
472         final RemoteCallback callback = intent.getParcelableExtra(EXTRA_REMOTE_READY_CALLBACK,
473                 RemoteCallback.class);
474         if (callback != null) {
475             callback.sendResult(null);
476         }
477     }
478 
awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName, String action, long timeoutMs)479     private void awaitPackageBroadcast(RemoteCallback remoteCallback, String packageName,
480             String action, long timeoutMs) {
481         final IntentFilter filter = new IntentFilter(action);
482         filter.addDataScheme("package");
483         filter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL);
484         final Object token = new Object();
485         registerReceiver(new BroadcastReceiver() {
486             @Override
487             public void onReceive(Context context, Intent intent) {
488                 final Bundle result = new Bundle();
489                 result.putString(EXTRA_DATA, intent.getDataString());
490                 remoteCallback.sendResult(result);
491                 mainHandler.removeCallbacksAndMessages(token);
492                 finish();
493             }
494         }, filter, Context.RECEIVER_EXPORTED);
495         mainHandler.postDelayed(
496                 () -> sendError(remoteCallback,
497                         new MissingBroadcastException(action, timeoutMs)),
498                 token, timeoutMs);
499     }
500 
awaitPackageRestartedBroadcast(RemoteCallback remoteCallback, String expectedPkgName, String action, long timeoutMs)501     private void awaitPackageRestartedBroadcast(RemoteCallback remoteCallback,
502             String expectedPkgName, String action, long timeoutMs) {
503         final IntentFilter filter = new IntentFilter(action);
504         filter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
505         final Object token = new Object();
506         final Bundle result = new Bundle();
507         final Uri expectedData = Uri.fromParts("package", expectedPkgName, null /* fragment */);
508         registerReceiver(new BroadcastReceiver() {
509             @Override
510             public void onReceive(Context context, Intent intent) {
511                 final String intentData = intent.getDataString();
512                 if (expectedData.toString().equals(intentData)) {
513                     mainHandler.removeCallbacksAndMessages(token);
514                     result.putString(Intent.EXTRA_PACKAGE_NAME, expectedPkgName);
515                     remoteCallback.sendResult(result);
516                     finish();
517                 }
518             }
519         }, filter, Context.RECEIVER_EXPORTED);
520         mainHandler.postDelayed(() -> remoteCallback.sendResult(result), token, timeoutMs);
521     }
522 
awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback, List<String> awaitList, String action, long timeoutMs)523     private void awaitSuspendedPackagesBroadcast(RemoteCallback remoteCallback,
524             List<String> awaitList, String action, long timeoutMs) {
525         final IntentFilter filter = new IntentFilter(action);
526         final ArrayList<String> suspendedList = new ArrayList<>();
527         final Object token = new Object();
528         final Runnable sendResult = () -> {
529             final Bundle result = new Bundle();
530             result.putStringArray(EXTRA_PACKAGES, suspendedList.toArray(new String[] {}));
531             remoteCallback.sendResult(result);
532             finish();
533         };
534         registerReceiver(new BroadcastReceiver() {
535             @Override
536             public void onReceive(Context context, Intent intent) {
537                 final Bundle extras = intent.getExtras();
538                 final String[] changedList = extras.getStringArray(
539                         Intent.EXTRA_CHANGED_PACKAGE_LIST);
540                 suspendedList.addAll(Arrays.stream(changedList).filter(
541                         p -> awaitList.contains(p)).collect(Collectors.toList()));
542                 if (suspendedList.size() == awaitList.size()) {
543                     mainHandler.removeCallbacksAndMessages(token);
544                     sendResult.run();
545                 }
546             }
547         }, filter, Context.RECEIVER_EXPORTED);
548         mainHandler.postDelayed(() -> sendResult.run(), token, timeoutMs);
549     }
550 
matchPackageNames(String[] expectedPackages, String[] actualPackages)551     private boolean matchPackageNames(String[] expectedPackages, String[] actualPackages) {
552         Arrays.sort(expectedPackages);
553         Arrays.sort(actualPackages);
554         return Arrays.equals(expectedPackages, actualPackages);
555     }
556 
awaitLauncherAppsCallback(RemoteCallback remoteCallback, int expectedEventCode, String[] expectedPackages, long timeoutMs)557     private void awaitLauncherAppsCallback(RemoteCallback remoteCallback, int expectedEventCode,
558             String[] expectedPackages, long timeoutMs) {
559         final Object token = new Object();
560         final Bundle result = new Bundle();
561         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
562         final LauncherApps.Callback launcherAppsCallback = new LauncherApps.Callback() {
563 
564             private void onPackageStateUpdated(String[] packageNames, int resultCode) {
565                 if (resultCode != expectedEventCode) {
566                     return;
567                 }
568                 if (!matchPackageNames(expectedPackages, packageNames)) {
569                     return;
570                 }
571 
572                 mainHandler.removeCallbacksAndMessages(token);
573                 result.putStringArray(EXTRA_PACKAGES, packageNames);
574                 result.putInt(EXTRA_FLAGS, resultCode);
575                 remoteCallback.sendResult(result);
576 
577                 launcherApps.unregisterCallback(this);
578                 finish();
579             }
580 
581             @Override
582             public void onPackageRemoved(String packageName, UserHandle user) {
583                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_REMOVED);
584             }
585 
586             @Override
587             public void onPackageAdded(String packageName, UserHandle user) {
588                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_ADDED);
589             }
590 
591             @Override
592             public void onPackageChanged(String packageName, UserHandle user) {
593                 onPackageStateUpdated(new String[]{packageName}, CALLBACK_EVENT_PACKAGE_CHANGED);
594             }
595 
596             @Override
597             public void onPackagesAvailable(String[] packageNames, UserHandle user,
598                     boolean replacing) {
599                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_AVAILABLE);
600             }
601 
602             @Override
603             public void onPackagesUnavailable(String[] packageNames, UserHandle user,
604                     boolean replacing) {
605                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_UNAVAILABLE);
606             }
607 
608             @Override
609             public void onPackagesSuspended(String[] packageNames, UserHandle user) {
610                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_SUSPENDED);
611                 super.onPackagesSuspended(packageNames, user);
612             }
613 
614             @Override
615             public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
616                 onPackageStateUpdated(packageNames, CALLBACK_EVENT_PACKAGES_UNSUSPENDED);
617                 super.onPackagesUnsuspended(packageNames, user);
618             }
619         };
620 
621         launcherApps.registerCallback(launcherAppsCallback);
622 
623         mainHandler.postDelayed(() -> {
624             result.putStringArray(EXTRA_PACKAGES, new String[]{});
625             result.putInt(EXTRA_FLAGS, CALLBACK_EVENT_INVALID);
626             remoteCallback.sendResult(result);
627 
628             launcherApps.unregisterCallback(launcherAppsCallback);
629             finish();
630         }, token, timeoutMs);
631     }
632 
sendGetInstalledPackages(RemoteCallback remoteCallback, int flags)633     private void sendGetInstalledPackages(RemoteCallback remoteCallback, int flags) {
634         String[] packages =
635                 getPackageManager().getInstalledPackages(PackageInfoFlags.of(flags))
636                         .stream().map(p -> p.packageName).distinct().toArray(String[]::new);
637         Bundle result = new Bundle();
638         result.putStringArray(EXTRA_RETURN_RESULT, packages);
639         remoteCallback.sendResult(result);
640         finish();
641     }
642 
sendQueryIntentActivities(RemoteCallback remoteCallback, Intent queryIntent)643     private void sendQueryIntentActivities(RemoteCallback remoteCallback, Intent queryIntent) {
644         final String[] resolveInfos = getPackageManager().queryIntentActivities(
645                 queryIntent, ResolveInfoFlags.of(0)).stream()
646                 .map(ri -> ri.activityInfo.applicationInfo.packageName)
647                 .distinct()
648                 .toArray(String[]::new);
649         Bundle result = new Bundle();
650         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
651         remoteCallback.sendResult(result);
652         finish();
653     }
654 
sendQueryIntentServices(RemoteCallback remoteCallback, Intent queryIntent)655     private void sendQueryIntentServices(RemoteCallback remoteCallback, Intent queryIntent) {
656         final String[] resolveInfos = getPackageManager().queryIntentServices(
657                 queryIntent, ResolveInfoFlags.of(0)).stream()
658                 .map(ri -> ri.serviceInfo.applicationInfo.packageName)
659                 .distinct()
660                 .toArray(String[]::new);
661         Bundle result = new Bundle();
662         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
663         remoteCallback.sendResult(result);
664         finish();
665     }
666 
sendQueryIntentProviders(RemoteCallback remoteCallback, Intent queryIntent)667     private void sendQueryIntentProviders(RemoteCallback remoteCallback, Intent queryIntent) {
668         final String[] resolveInfos = getPackageManager().queryIntentContentProviders(
669                 queryIntent, ResolveInfoFlags.of(0)).stream()
670                 .map(ri -> ri.providerInfo.applicationInfo.packageName)
671                 .distinct()
672                 .toArray(String[]::new);
673         Bundle result = new Bundle();
674         result.putStringArray(EXTRA_RETURN_RESULT, resolveInfos);
675         remoteCallback.sendResult(result);
676         finish();
677     }
678 
queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority)679     private void queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority) {
680         backgroundHandler.post(() -> {
681             Uri queryUri = Uri.parse("content://" + authority + "/test");
682             Cursor query = getContentResolver().query(queryUri, null, null, null, null);
683             if (query == null || !query.moveToFirst()) {
684                 sendError(remoteCallback,
685                         new IllegalStateException(
686                                 "Query of " + queryUri + " could not be completed"));
687                 return;
688             }
689             ArrayList<String> visiblePackages = new ArrayList<>();
690             while (!query.isAfterLast()) {
691                 visiblePackages.add(query.getString(0));
692                 query.moveToNext();
693             }
694             query.close();
695 
696             mainHandler.post(() -> {
697                 Bundle result = new Bundle();
698                 result.putStringArray(EXTRA_RETURN_RESULT, visiblePackages.toArray(new String[]{}));
699                 remoteCallback.sendResult(result);
700                 finish();
701             });
702 
703         });
704     }
705 
sendError(RemoteCallback remoteCallback, Exception failure)706     private void sendError(RemoteCallback remoteCallback, Exception failure) {
707         Bundle result = new Bundle();
708         result.putSerializable(EXTRA_ERROR, failure);
709         if (remoteCallback != null) {
710             remoteCallback.sendResult(result);
711         }
712         finish();
713     }
714 
sendPackageInfo(RemoteCallback remoteCallback, String packageName)715     private void sendPackageInfo(RemoteCallback remoteCallback, String packageName) {
716         final PackageInfo pi;
717         try {
718             pi = getPackageManager().getPackageInfo(packageName, PackageInfoFlags.of(0));
719         } catch (PackageManager.NameNotFoundException e) {
720             sendError(remoteCallback, e);
721             return;
722         }
723         Bundle result = new Bundle();
724         result.putParcelable(EXTRA_RETURN_RESULT, pi);
725         remoteCallback.sendResult(result);
726         finish();
727     }
728 
sendPackagesForUid(RemoteCallback remoteCallback, int uid)729     private void sendPackagesForUid(RemoteCallback remoteCallback, int uid) {
730         final String[] packages = getPackageManager().getPackagesForUid(uid);
731         final Bundle result = new Bundle();
732         result.putStringArray(EXTRA_RETURN_RESULT, packages);
733         remoteCallback.sendResult(result);
734         finish();
735     }
736 
sendNameForUid(RemoteCallback remoteCallback, int uid)737     private void sendNameForUid(RemoteCallback remoteCallback, int uid) {
738         final String name = getPackageManager().getNameForUid(uid);
739         final Bundle result = new Bundle();
740         result.putString(EXTRA_RETURN_RESULT, name);
741         remoteCallback.sendResult(result);
742         finish();
743     }
744 
sendNamesForUids(RemoteCallback remoteCallback, int uid)745     private void sendNamesForUids(RemoteCallback remoteCallback, int uid) {
746         final String[] names = getPackageManager().getNamesForUids(new int[]{uid});
747         final Bundle result = new Bundle();
748         result.putStringArray(EXTRA_RETURN_RESULT, names);
749         remoteCallback.sendResult(result);
750         finish();
751     }
752 
sendCheckSignatures(RemoteCallback remoteCallback, int uid1, int uid2)753     private void sendCheckSignatures(RemoteCallback remoteCallback, int uid1, int uid2) {
754         final int signatureResult = getPackageManager().checkSignatures(uid1, uid2);
755         final Bundle result = new Bundle();
756         result.putInt(EXTRA_RETURN_RESULT, signatureResult);
757         remoteCallback.sendResult(result);
758         finish();
759     }
760 
sendHasSigningCertificate(RemoteCallback remoteCallback, int uid, byte[] cert, int type)761     private void sendHasSigningCertificate(RemoteCallback remoteCallback, int uid, byte[] cert,
762             int type) {
763         final boolean signatureResult = getPackageManager().hasSigningCertificate(uid, cert, type);
764         final Bundle result = new Bundle();
765         result.putBoolean(EXTRA_RETURN_RESULT, signatureResult);
766         remoteCallback.sendResult(result);
767         finish();
768     }
769 
770     /**
771      * Instead of sending a list of package names, this function sends a List of
772      * {@link SyncAdapterType}, since the {@link SyncAdapterType#getPackageName()} is a test api
773      * which can only be invoked in the instrumentation.
774      */
sendSyncAdapterTypes(RemoteCallback remoteCallback)775     private void sendSyncAdapterTypes(RemoteCallback remoteCallback) {
776         final SyncAdapterType[] types = ContentResolver.getSyncAdapterTypes();
777         final ArrayList<Parcelable> parcelables = new ArrayList<>();
778         for (SyncAdapterType type : types) {
779             parcelables.add(type);
780         }
781         final Bundle result = new Bundle();
782         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
783         remoteCallback.sendResult(result);
784         finish();
785     }
786 
sendIsActivityEnabled(RemoteCallback remoteCallback, ComponentName componentName)787     private void sendIsActivityEnabled(RemoteCallback remoteCallback, ComponentName componentName) {
788         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
789         final Bundle result = new Bundle();
790         try {
791             result.putBoolean(EXTRA_RETURN_RESULT, launcherApps.isActivityEnabled(componentName,
792                     Process.myUserHandle()));
793         } catch (IllegalArgumentException e) {
794         }
795         remoteCallback.sendResult(result);
796         finish();
797     }
798 
sendGetSuspendedPackageLauncherExtras(RemoteCallback remoteCallback, String packageName)799     private void sendGetSuspendedPackageLauncherExtras(RemoteCallback remoteCallback,
800             String packageName) {
801         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
802         final Bundle result = new Bundle();
803         try {
804             result.putBundle(EXTRA_RETURN_RESULT,
805                     launcherApps.getSuspendedPackageLauncherExtras(packageName,
806                             Process.myUserHandle()));
807         } catch (IllegalArgumentException e) {
808         }
809         remoteCallback.sendResult(result);
810         finish();
811     }
812 
sendInstalledAppWidgetProviders(RemoteCallback remoteCallback)813     private void sendInstalledAppWidgetProviders(RemoteCallback remoteCallback) {
814         final AppWidgetManager appWidgetManager = getSystemService(AppWidgetManager.class);
815         final List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
816         final ArrayList<Parcelable> parcelables = new ArrayList<>();
817         for (AppWidgetProviderInfo info : providers) {
818             parcelables.add(info);
819         }
820         final Bundle result = new Bundle();
821         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
822         remoteCallback.sendResult(result);
823         finish();
824     }
825 
sendSyncAdapterPackagesForAuthorityAsUser(RemoteCallback remoteCallback, String authority, int userId)826     private void sendSyncAdapterPackagesForAuthorityAsUser(RemoteCallback remoteCallback,
827             String authority, int userId) {
828         final String[] syncAdapterPackages = ContentResolver
829                 .getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
830         final Bundle result = new Bundle();
831         result.putStringArray(Intent.EXTRA_PACKAGES, syncAdapterPackages);
832         remoteCallback.sendResult(result);
833         finish();
834     }
835 
awaitRequestSyncStatus(RemoteCallback remoteCallback, String action, Account account, String authority, long timeoutMs)836     private void awaitRequestSyncStatus(RemoteCallback remoteCallback, String action,
837             Account account, String authority, long timeoutMs) {
838         ContentResolver.cancelSync(account, authority);
839         final Object token = new Object();
840         final SyncStatusObserver observer = which -> {
841             final Bundle result = new Bundle();
842             result.putBoolean(EXTRA_RETURN_RESULT, true);
843             remoteCallback.sendResult(result);
844             mainHandler.removeCallbacksAndMessages(token);
845             finish();
846         };
847         syncStatusHandle = ContentResolver.addStatusChangeListener(
848                 ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
849                         | ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS
850                         | ContentResolver.SYNC_OBSERVER_TYPE_PENDING, observer);
851 
852         ContentResolver.requestSync(account, authority, new Bundle());
853         mainHandler.postDelayed(
854                 () -> sendError(remoteCallback, new MissingCallbackException(action, timeoutMs)),
855                 token, timeoutMs);
856     }
857 
sendGetSyncAdapterControlPanel(RemoteCallback remoteCallback, Account account, String authority, ComponentName componentName)858     private void sendGetSyncAdapterControlPanel(RemoteCallback remoteCallback, Account account,
859             String authority, ComponentName componentName) {
860         ContentResolver.cancelSync(account, authority);
861         ContentResolver.requestSync(account, authority, new Bundle());
862         final ActivityManager activityManager = getSystemService(ActivityManager.class);
863         final PendingIntent pendingIntent =
864                 activityManager.getRunningServiceControlPanel(componentName);
865         final Bundle result = new Bundle();
866         result.putParcelable(EXTRA_RETURN_RESULT, pendingIntent);
867         remoteCallback.sendResult(result);
868         finish();
869     }
870 
awaitRequestPeriodicSync(RemoteCallback remoteCallback, Account account, String authority, long timeoutMs)871     private void awaitRequestPeriodicSync(RemoteCallback remoteCallback, Account account,
872             String authority, long timeoutMs) {
873         ContentResolver.addPeriodicSync(account, authority, Bundle.EMPTY,
874                 TimeUnit.HOURS.toSeconds(1));
875         final Object token = new Object();
876         final Bundle result = new Bundle();
877         final Runnable pollingPeriodicSync = new Runnable() {
878             @Override
879             public void run() {
880                 if (!ContentResolver.getPeriodicSyncs(account, authority).stream()
881                         .anyMatch(sync -> sync.authority.equals(authority))) {
882                     mainHandler.postDelayed(this, 100 /* delayMillis */);
883                     return;
884                 }
885                 mainHandler.removeCallbacksAndMessages(token);
886                 result.putBoolean(EXTRA_RETURN_RESULT, true);
887                 remoteCallback.sendResult(result);
888                 finish();
889             }
890         };
891 
892         mainHandler.post(pollingPeriodicSync);
893         mainHandler.postDelayed(() -> {
894             mainHandler.removeCallbacks(pollingPeriodicSync);
895             result.putBoolean(EXTRA_RETURN_RESULT, false);
896             remoteCallback.sendResult(result);
897             finish();
898         }, token, timeoutMs);
899     }
900 
setSyncAutomatically(RemoteCallback remoteCallback, Account account, String authority)901     private void setSyncAutomatically(RemoteCallback remoteCallback, Account account,
902             String authority) {
903         ContentResolver.setSyncAutomatically(account, authority, true /* sync */);
904         remoteCallback.sendResult(null);
905         finish();
906     }
907 
getSyncAutomatically(RemoteCallback remoteCallback, String authority)908     private void getSyncAutomatically(RemoteCallback remoteCallback, String authority) {
909         final boolean ret = ContentResolver.getSyncAutomatically(null /* account */, authority);
910         final Bundle result = new Bundle();
911         result.putBoolean(EXTRA_RETURN_RESULT, ret);
912         remoteCallback.sendResult(result);
913         finish();
914     }
915 
getIsSyncable(RemoteCallback remoteCallback, Account account, String authority)916     private void getIsSyncable(RemoteCallback remoteCallback, Account account,
917             String authority) {
918         final int ret = ContentResolver.getIsSyncable(account, authority);
919         final Bundle result = new Bundle();
920         result.putInt(EXTRA_RETURN_RESULT, ret);
921         remoteCallback.sendResult(result);
922         finish();
923     }
924 
getPeriodicSyncs(RemoteCallback remoteCallback, Account account, String authority)925     private void getPeriodicSyncs(RemoteCallback remoteCallback, Account account,
926             String authority) {
927         final List<PeriodicSync> periodicSyncList =
928                 ContentResolver.getPeriodicSyncs(account, authority);
929         final ArrayList<Parcelable> parcelables = new ArrayList<>();
930         for (PeriodicSync sync : periodicSyncList) {
931             parcelables.add(sync);
932         }
933         final Bundle result = new Bundle();
934         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
935         remoteCallback.sendResult(result);
936         finish();
937     }
938 
sendGetSharedLibraryDependentPackages(RemoteCallback remoteCallback, String sharedLibName)939     private void sendGetSharedLibraryDependentPackages(RemoteCallback remoteCallback,
940             String sharedLibName) {
941         final List<SharedLibraryInfo> sharedLibraryInfos = getPackageManager()
942                 .getSharedLibraries(0 /* flags */);
943         SharedLibraryInfo sharedLibraryInfo = sharedLibraryInfos.stream().filter(
944                 info -> sharedLibName.equals(info.getName())).findAny().orElse(null);
945         final String[] dependentPackages = sharedLibraryInfo == null ? null
946                 : sharedLibraryInfo.getDependentPackages().stream()
947                         .map(versionedPackage -> versionedPackage.getPackageName())
948                         .distinct().collect(Collectors.toList()).toArray(new String[]{});
949         final Bundle result = new Bundle();
950         result.putStringArray(Intent.EXTRA_PACKAGES, dependentPackages);
951         remoteCallback.sendResult(result);
952         finish();
953     }
954 
sendGetPreferredActivities(RemoteCallback remoteCallback)955     private void sendGetPreferredActivities(RemoteCallback remoteCallback) {
956         final List<IntentFilter> filters = new ArrayList<>();
957         final List<ComponentName> activities = new ArrayList<>();
958         getPackageManager().getPreferredActivities(filters, activities, null /* packageName*/);
959         final String[] packages = activities.stream()
960                 .map(componentName -> componentName.getPackageName()).distinct()
961                 .collect(Collectors.toList()).toArray(new String[]{});
962         final Bundle result = new Bundle();
963         result.putStringArray(Intent.EXTRA_PACKAGES, packages);
964         remoteCallback.sendResult(result);
965         finish();
966     }
967 
sendSetInstallerPackageName(RemoteCallback remoteCallback, String targetPackageName, String installerPackageName)968     private void sendSetInstallerPackageName(RemoteCallback remoteCallback,
969             String targetPackageName, String installerPackageName) {
970         try {
971             getPackageManager().setInstallerPackageName(targetPackageName, installerPackageName);
972             remoteCallback.sendResult(null);
973             finish();
974         } catch (Exception e) {
975             sendError(remoteCallback, e);
976         }
977     }
978 
sendLauncherAppsShouldHideFromSuggestions(RemoteCallback remoteCallback, String targetPackageName, int userId)979     private void sendLauncherAppsShouldHideFromSuggestions(RemoteCallback remoteCallback,
980             String targetPackageName, int userId) {
981         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
982         final boolean hideFromSuggestions = launcherApps.shouldHideFromSuggestions(
983                 targetPackageName, UserHandle.of(userId));
984         final Bundle result = new Bundle();
985         result.putBoolean(EXTRA_RETURN_RESULT, hideFromSuggestions);
986         remoteCallback.sendResult(result);
987         finish();
988     }
989 
sendCheckUriPermission(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName, int targetUid)990     private void sendCheckUriPermission(RemoteCallback remoteCallback, String sourceAuthority,
991             String targetPackageName, int targetUid) {
992         Uri uri = getContentUriAndGrantRead(sourceAuthority, targetPackageName);
993         final int permissionResult = checkUriPermission(uri, 0 /* pid */, targetUid,
994                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
995         revokeReadFromUriAndSendPermissionResult(uri, permissionResult, remoteCallback);
996     }
997 
sendCheckContentUriPermissionFull(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName, int targetUid)998     private void sendCheckContentUriPermissionFull(RemoteCallback remoteCallback,
999             String sourceAuthority, String targetPackageName, int targetUid) {
1000         Uri uri = getContentUriAndGrantRead(sourceAuthority, targetPackageName);
1001         final int permissionResult = checkContentUriPermissionFull(uri, 0 /* pid */, targetUid,
1002                 Intent.FLAG_GRANT_READ_URI_PERMISSION);
1003         revokeReadFromUriAndSendPermissionResult(uri, permissionResult, remoteCallback);
1004     }
1005 
getContentUriAndGrantRead(String sourceAuthority, String targetPackageName)1006     private Uri getContentUriAndGrantRead(String sourceAuthority, String targetPackageName) {
1007         final Uri uri = Uri.parse("content://" + sourceAuthority);
1008         grantUriPermission(targetPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1009         return uri;
1010     }
1011 
revokeReadFromUriAndSendPermissionResult(Uri uri, int permissionResult, RemoteCallback remoteCallback)1012     private void revokeReadFromUriAndSendPermissionResult(Uri uri, int permissionResult,
1013             RemoteCallback remoteCallback) {
1014         revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1015         final Bundle result = new Bundle();
1016         result.putInt(EXTRA_RETURN_RESULT, permissionResult);
1017         remoteCallback.sendResult(result);
1018         finish();
1019     }
1020 
sendGrantUriPermission(RemoteCallback remoteCallback, String sourceAuthority, String targetPackageName)1021     private void sendGrantUriPermission(RemoteCallback remoteCallback, String sourceAuthority,
1022             String targetPackageName) {
1023         final Uri uri = Uri.parse("content://" + sourceAuthority);
1024         grantUriPermission(targetPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1025         remoteCallback.sendResult(null);
1026         finish();
1027     }
1028 
sendRevokeUriPermission(RemoteCallback remoteCallback, String sourceAuthority)1029     private void sendRevokeUriPermission(RemoteCallback remoteCallback, String sourceAuthority) {
1030         final Uri uri = Uri.parse("content://" + sourceAuthority);
1031         revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
1032         remoteCallback.sendResult(null);
1033         finish();
1034     }
1035 
sendCanPackageQuery(RemoteCallback remoteCallback, String sourcePackageName, String targetPackageName)1036     private void sendCanPackageQuery(RemoteCallback remoteCallback, String sourcePackageName,
1037             String targetPackageName) {
1038         try {
1039             final boolean visibility = getPackageManager().canPackageQuery(sourcePackageName,
1040                     targetPackageName);
1041             final Bundle result = new Bundle();
1042             result.putBoolean(EXTRA_RETURN_RESULT, visibility);
1043             remoteCallback.sendResult(result);
1044             finish();
1045         } catch (PackageManager.NameNotFoundException e) {
1046             sendError(remoteCallback, e);
1047         }
1048     }
1049 
sendCanPackageQueries(RemoteCallback remoteCallback, String sourcePackageName, String[] targetPackageNames)1050     private void sendCanPackageQueries(RemoteCallback remoteCallback, String sourcePackageName,
1051             String[] targetPackageNames) {
1052         try {
1053             final boolean[] visibilities = getPackageManager().canPackageQuery(sourcePackageName,
1054                     targetPackageNames);
1055             final Bundle result = new Bundle();
1056             result.putBooleanArray(EXTRA_RETURN_RESULT, visibilities);
1057             remoteCallback.sendResult(result);
1058             finish();
1059         } catch (PackageManager.NameNotFoundException e) {
1060             sendError(remoteCallback, e);
1061         }
1062     }
1063 
sendSessionInfosListResult(RemoteCallback remoteCallback, List<SessionInfo> infos)1064     private void sendSessionInfosListResult(RemoteCallback remoteCallback,
1065             List<SessionInfo> infos) {
1066         final ArrayList<Parcelable> parcelables = new ArrayList<>(infos);
1067         for (SessionInfo info : infos) {
1068             parcelables.add(info);
1069         }
1070         final Bundle result = new Bundle();
1071         result.putParcelableArrayList(EXTRA_RETURN_RESULT, parcelables);
1072         remoteCallback.sendResult(result);
1073         finish();
1074     }
1075 
sendGetContentProviderMimeType(RemoteCallback remoteCallback, String authority)1076     private void sendGetContentProviderMimeType(RemoteCallback remoteCallback, String authority) {
1077         final Uri uri = Uri.parse("content://" + authority);
1078         final ContentResolver resolver = getContentResolver();
1079         final String mimeType = resolver.getType(uri);
1080         final Bundle result = new Bundle();
1081         result.putString(EXTRA_RETURN_RESULT, mimeType);
1082         remoteCallback.sendResult(result);
1083         finish();
1084     }
1085 
awaitLauncherAppsSessionCallback(RemoteCallback remoteCallback, int expectedSessionId, long timeoutMs)1086     private void awaitLauncherAppsSessionCallback(RemoteCallback remoteCallback,
1087             int expectedSessionId, long timeoutMs) {
1088         final Object token = new Object();
1089         final Bundle result = new Bundle();
1090         final LauncherApps launcherApps = getSystemService(LauncherApps.class);
1091         final SessionCallback sessionCallback = new SessionCallback() {
1092 
1093             @Override
1094             public void onCreated(int sessionId) {
1095                 // No-op
1096             }
1097 
1098             @Override
1099             public void onBadgingChanged(int sessionId) {
1100                 // No-op
1101             }
1102 
1103             @Override
1104             public void onActiveChanged(int sessionId, boolean active) {
1105                 // No-op
1106             }
1107 
1108             @Override
1109             public void onProgressChanged(int sessionId, float progress) {
1110                 // No-op
1111             }
1112 
1113             @Override
1114             public void onFinished(int sessionId, boolean success) {
1115                 if (sessionId != expectedSessionId) {
1116                     return;
1117                 }
1118 
1119                 mainHandler.removeCallbacksAndMessages(token);
1120                 result.putInt(EXTRA_ID, sessionId);
1121                 remoteCallback.sendResult(result);
1122 
1123                 launcherApps.unregisterPackageInstallerSessionCallback(this);
1124                 finish();
1125             }
1126         };
1127 
1128         launcherApps.registerPackageInstallerSessionCallback(this.getMainExecutor(),
1129                 sessionCallback);
1130 
1131         mainHandler.postDelayed(() -> {
1132             result.putInt(EXTRA_ID, SessionInfo.INVALID_ID);
1133             remoteCallback.sendResult(result);
1134 
1135             launcherApps.unregisterPackageInstallerSessionCallback(sessionCallback);
1136             finish();
1137         }, token, timeoutMs);
1138     }
1139 
sendPendingIntentGetActivity(RemoteCallback remoteCallback)1140     private void sendPendingIntentGetActivity(RemoteCallback remoteCallback) {
1141         final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* requestCode */,
1142                 new Intent(this, TestActivity.class), PendingIntent.FLAG_IMMUTABLE);
1143         final Bundle result = new Bundle();
1144         result.putParcelable(EXTRA_PENDING_INTENT, pendingIntent);
1145         remoteCallback.sendResult(result);
1146         finish();
1147     }
1148 
sendPendingIntentGetCreatorPackage(RemoteCallback remoteCallback, PendingIntent pendingIntent)1149     private void sendPendingIntentGetCreatorPackage(RemoteCallback remoteCallback,
1150             PendingIntent pendingIntent) {
1151         final Bundle result = new Bundle();
1152         result.putString(Intent.EXTRA_PACKAGE_NAME, pendingIntent.getCreatorPackage());
1153         remoteCallback.sendResult(result);
1154         finish();
1155     }
1156 
sendCheckPackageResult(RemoteCallback remoteCallback, String packageName, int uid)1157     private void sendCheckPackageResult(RemoteCallback remoteCallback, String packageName,
1158             int uid) {
1159         try {
1160             getSystemService(AppOpsManager.class).checkPackage(uid, packageName);
1161             final Bundle result = new Bundle();
1162             result.putBoolean(EXTRA_RETURN_RESULT, true);
1163             remoteCallback.sendResult(result);
1164             finish();
1165         } catch (SecurityException e) {
1166             sendError(remoteCallback, e);
1167         }
1168     }
1169 
sendGetEnabledSpellCheckerInfos(RemoteCallback remoteCallback)1170     private void sendGetEnabledSpellCheckerInfos(RemoteCallback remoteCallback) {
1171         final TextServicesManager tsm = getSystemService(TextServicesManager.class);
1172         final ArrayList<SpellCheckerInfo> infos =
1173                 new ArrayList<>(tsm.getEnabledSpellCheckerInfos());
1174         final Bundle result = new Bundle();
1175         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1176         remoteCallback.sendResult(result);
1177         finish();
1178     }
1179 
sendGetInputMethodList(RemoteCallback remoteCallback)1180     private void sendGetInputMethodList(RemoteCallback remoteCallback) {
1181         final InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
1182         final ArrayList<InputMethodInfo> infos =
1183                 new ArrayList<>(inputMethodManager.getInputMethodList());
1184         final Bundle result = new Bundle();
1185         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1186         remoteCallback.sendResult(result);
1187         finish();
1188     }
1189 
sendGetEnabledInputMethodList(RemoteCallback remoteCallback)1190     private void sendGetEnabledInputMethodList(RemoteCallback remoteCallback) {
1191         final InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
1192         final ArrayList<InputMethodInfo> infos =
1193                 new ArrayList<>(inputMethodManager.getEnabledInputMethodList());
1194         final Bundle result = new Bundle();
1195         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1196         remoteCallback.sendResult(result);
1197         finish();
1198     }
1199 
sendGetEnabledInputMethodSubtypeList(RemoteCallback remoteCallback, InputMethodInfo targetImi)1200     private void sendGetEnabledInputMethodSubtypeList(RemoteCallback remoteCallback,
1201             InputMethodInfo targetImi) {
1202         final InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
1203         final ArrayList<InputMethodSubtype> infos = new ArrayList<>(
1204                 inputMethodManager.getEnabledInputMethodSubtypeList(targetImi, true));
1205         final Bundle result = new Bundle();
1206         result.putParcelableArrayList(EXTRA_RETURN_RESULT, infos);
1207         remoteCallback.sendResult(result);
1208         finish();
1209     }
1210 
sendAccountManagerGetAuthenticatorTypes(RemoteCallback remoteCallback)1211     private void sendAccountManagerGetAuthenticatorTypes(RemoteCallback remoteCallback) {
1212         final AccountManager accountManager = AccountManager.get(this);
1213         final Bundle result = new Bundle();
1214         result.putParcelableArray(EXTRA_RETURN_RESULT, accountManager.getAuthenticatorTypes());
1215         remoteCallback.sendResult(result);
1216         finish();
1217     }
1218 
sendMediaSessionManagerIsTrustedForMediaControl(RemoteCallback remoteCallback, String packageName, int uid)1219     private void sendMediaSessionManagerIsTrustedForMediaControl(RemoteCallback remoteCallback,
1220             String packageName, int uid) {
1221         final MediaSessionManager mediaSessionManager =
1222                 getSystemService(MediaSessionManager.class);
1223         final MediaSessionManager.RemoteUserInfo userInfo =
1224                 new MediaSessionManager.RemoteUserInfo(packageName, 0 /* pid */, uid);
1225         final boolean isTrusted = mediaSessionManager.isTrustedForMediaControl(userInfo);
1226         final Bundle result = new Bundle();
1227         result.putBoolean(EXTRA_RETURN_RESULT, isTrusted);
1228         remoteCallback.sendResult(result);
1229         finish();
1230     }
1231 
1232     @Override
onActivityResult(int requestCode, int resultCode, Intent data)1233     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1234         super.onActivityResult(requestCode, resultCode, data);
1235         final RemoteCallback remoteCallback = callbacks.get(requestCode);
1236         if (resultCode != RESULT_OK) {
1237             final Exception e = data.getSerializableExtra(EXTRA_ERROR, Exception.class);
1238             sendError(remoteCallback, e == null ? new Exception("Result was " + resultCode) : e);
1239             return;
1240         }
1241         final Bundle result = new Bundle();
1242         result.putParcelable(EXTRA_RETURN_RESULT, data.getParcelableExtra(EXTRA_RETURN_RESULT));
1243         remoteCallback.sendResult(result);
1244         finish();
1245     }
1246 
bindService(RemoteCallback remoteCallback, String packageName)1247     private void bindService(RemoteCallback remoteCallback, String packageName) {
1248         final Intent intent = new Intent(ACTION_MANIFEST_SERVICE);
1249         intent.setClassName(packageName, SERVICE_CLASS_DUMMY_SERVICE);
1250         final ServiceConnection serviceConnection = new ServiceConnection() {
1251             @Override
1252             public void onServiceConnected(ComponentName className, IBinder service) {
1253                 // No-op
1254             }
1255 
1256             @Override
1257             public void onServiceDisconnected(ComponentName className) {
1258                 // No-op
1259             }
1260 
1261             @Override
1262             public void onBindingDied(ComponentName name) {
1263                 // Remote service die
1264                 finish();
1265             }
1266 
1267             @Override
1268             public void onNullBinding(ComponentName name) {
1269                 // Since the DummyService doesn't implement onBind, it returns null and
1270                 // onNullBinding would be called. Use postDelayed to keep this service
1271                 // connection alive for 3 seconds.
1272                 mainHandler.postDelayed(() -> {
1273                     unbindService(this);
1274                     finish();
1275                 }, TIMEOUT_MS);
1276             }
1277         };
1278 
1279         final boolean bound = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
1280         final Bundle result = new Bundle();
1281         result.putBoolean(EXTRA_RETURN_RESULT, bound);
1282         remoteCallback.sendResult(result);
1283         // Don't invoke finish() right here if service is bound successfully to keep the service
1284         // connection alive since the ServiceRecord would be removed from the ServiceMap once no
1285         // client is binding the service.
1286         if (!bound) finish();
1287     }
1288 }
1289