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