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