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