1 /* 2 * Copyright (C) 2006 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.app; 18 19 import static android.content.pm.PackageManager.PERMISSION_DENIED; 20 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21 import static android.os.StrictMode.vmIncorrectContextUseEnabled; 22 import static android.view.WindowManager.LayoutParams.WindowType; 23 24 import android.annotation.IntDef; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.UiContext; 28 import android.compat.annotation.UnsupportedAppUsage; 29 import android.content.AttributionSource; 30 import android.content.AutofillOptions; 31 import android.content.BroadcastReceiver; 32 import android.content.ComponentName; 33 import android.content.ContentCaptureOptions; 34 import android.content.ContentProvider; 35 import android.content.ContentResolver; 36 import android.content.Context; 37 import android.content.ContextParams; 38 import android.content.ContextWrapper; 39 import android.content.IContentProvider; 40 import android.content.IIntentReceiver; 41 import android.content.Intent; 42 import android.content.IntentFilter; 43 import android.content.IntentSender; 44 import android.content.ReceiverCallNotAllowedException; 45 import android.content.ServiceConnection; 46 import android.content.SharedPreferences; 47 import android.content.pm.ActivityInfo; 48 import android.content.pm.ApplicationInfo; 49 import android.content.pm.IPackageManager; 50 import android.content.pm.PackageManager; 51 import android.content.pm.PackageManager.NameNotFoundException; 52 import android.content.res.AssetManager; 53 import android.content.res.CompatResources; 54 import android.content.res.CompatibilityInfo; 55 import android.content.res.Configuration; 56 import android.content.res.Resources; 57 import android.content.res.loader.ResourcesLoader; 58 import android.database.DatabaseErrorHandler; 59 import android.database.sqlite.SQLiteDatabase; 60 import android.database.sqlite.SQLiteDatabase.CursorFactory; 61 import android.graphics.Bitmap; 62 import android.graphics.drawable.Drawable; 63 import android.net.Uri; 64 import android.os.Binder; 65 import android.os.Build; 66 import android.os.Bundle; 67 import android.os.Debug; 68 import android.os.Environment; 69 import android.os.FileUtils; 70 import android.os.Handler; 71 import android.os.IBinder; 72 import android.os.Looper; 73 import android.os.Process; 74 import android.os.RemoteException; 75 import android.os.StrictMode; 76 import android.os.Trace; 77 import android.os.UserHandle; 78 import android.os.UserManager; 79 import android.os.storage.StorageManager; 80 import android.permission.PermissionManager; 81 import android.system.ErrnoException; 82 import android.system.Os; 83 import android.system.OsConstants; 84 import android.system.StructStat; 85 import android.text.TextUtils; 86 import android.util.AndroidRuntimeException; 87 import android.util.ArrayMap; 88 import android.util.Log; 89 import android.util.Slog; 90 import android.view.Display; 91 import android.view.DisplayAdjustments; 92 import android.view.autofill.AutofillManager.AutofillClient; 93 import android.window.WindowContext; 94 import android.window.WindowTokenClient; 95 96 import com.android.internal.annotations.GuardedBy; 97 import com.android.internal.util.Preconditions; 98 99 import dalvik.system.BlockGuard; 100 101 import libcore.io.Memory; 102 103 import java.io.File; 104 import java.io.FileInputStream; 105 import java.io.FileNotFoundException; 106 import java.io.FileOutputStream; 107 import java.io.FilenameFilter; 108 import java.io.IOException; 109 import java.io.InputStream; 110 import java.lang.annotation.Retention; 111 import java.lang.annotation.RetentionPolicy; 112 import java.nio.ByteOrder; 113 import java.nio.file.Path; 114 import java.util.ArrayList; 115 import java.util.Arrays; 116 import java.util.List; 117 import java.util.Objects; 118 import java.util.Set; 119 import java.util.concurrent.Executor; 120 121 class ReceiverRestrictedContext extends ContextWrapper { 122 @UnsupportedAppUsage ReceiverRestrictedContext(Context base)123 ReceiverRestrictedContext(Context base) { 124 super(base); 125 } 126 127 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)128 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 129 return registerReceiver(receiver, filter, null, null); 130 } 131 132 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)133 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 134 String broadcastPermission, Handler scheduler) { 135 if (receiver == null) { 136 // Allow retrieving current sticky broadcast; this is safe since we 137 // aren't actually registering a receiver. 138 return super.registerReceiver(null, filter, broadcastPermission, scheduler); 139 } else { 140 throw new ReceiverCallNotAllowedException( 141 "BroadcastReceiver components are not allowed to register to receive intents"); 142 } 143 } 144 145 @Override registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)146 public Intent registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, 147 String broadcastPermission, Handler scheduler) { 148 return registerReceiverAsUser( 149 receiver, UserHandle.ALL, filter, broadcastPermission, scheduler); 150 } 151 152 @Override registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)153 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 154 IntentFilter filter, String broadcastPermission, Handler scheduler) { 155 if (receiver == null) { 156 // Allow retrieving current sticky broadcast; this is safe since we 157 // aren't actually registering a receiver. 158 return super.registerReceiverAsUser(null, user, filter, broadcastPermission, scheduler); 159 } else { 160 throw new ReceiverCallNotAllowedException( 161 "BroadcastReceiver components are not allowed to register to receive intents"); 162 } 163 } 164 165 @Override bindService(Intent service, ServiceConnection conn, int flags)166 public boolean bindService(Intent service, ServiceConnection conn, int flags) { 167 throw new ReceiverCallNotAllowedException( 168 "BroadcastReceiver components are not allowed to bind to services"); 169 } 170 171 @Override bindService( Intent service, int flags, Executor executor, ServiceConnection conn)172 public boolean bindService( 173 Intent service, int flags, Executor executor, ServiceConnection conn) { 174 throw new ReceiverCallNotAllowedException( 175 "BroadcastReceiver components are not allowed to bind to services"); 176 } 177 178 @Override bindIsolatedService(Intent service, int flags, String instanceName, Executor executor, ServiceConnection conn)179 public boolean bindIsolatedService(Intent service, int flags, String instanceName, 180 Executor executor, ServiceConnection conn) { 181 throw new ReceiverCallNotAllowedException( 182 "BroadcastReceiver components are not allowed to bind to services"); 183 } 184 } 185 186 /** 187 * Common implementation of Context API, which provides the base 188 * context object for Activity and other application components. 189 */ 190 class ContextImpl extends Context { 191 private final static String TAG = "ContextImpl"; 192 private final static boolean DEBUG = false; 193 194 private static final String XATTR_INODE_CACHE = "user.inode_cache"; 195 private static final String XATTR_INODE_CODE_CACHE = "user.inode_code_cache"; 196 197 /** 198 * Map from package name, to preference name, to cached preferences. 199 */ 200 @GuardedBy("ContextImpl.class") 201 @UnsupportedAppUsage 202 private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefsCache; 203 204 /** 205 * Map from preference name to generated path. 206 */ 207 @GuardedBy("ContextImpl.class") 208 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 209 private ArrayMap<String, File> mSharedPrefsPaths; 210 211 @UnsupportedAppUsage 212 final @NonNull ActivityThread mMainThread; 213 @UnsupportedAppUsage 214 final @NonNull LoadedApk mPackageInfo; 215 @UnsupportedAppUsage 216 private @Nullable ClassLoader mClassLoader; 217 218 private final @Nullable IBinder mToken; 219 220 private final @NonNull UserHandle mUser; 221 222 @UnsupportedAppUsage 223 private final ApplicationContentResolver mContentResolver; 224 225 @UnsupportedAppUsage 226 private final String mBasePackageName; 227 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 228 private final String mOpPackageName; 229 private final @NonNull ContextParams mParams; 230 private final @NonNull AttributionSource mAttributionSource; 231 232 private final @NonNull ResourcesManager mResourcesManager; 233 @UnsupportedAppUsage 234 private @NonNull Resources mResources; 235 private @Nullable Display mDisplay; // may be null if invalid display or not initialized yet. 236 237 /** 238 * If set to {@code true} the resources for this context will be configured for mDisplay which 239 * will override the display configuration inherited from {@link #mToken} (or the global 240 * configuration if mToken is null). Typically set for display contexts and contexts derived 241 * from display contexts where changes to the activity display and the global configuration 242 * display should not impact their resources. 243 */ 244 private boolean mForceDisplayOverrideInResources; 245 246 /** @see Context#isConfigurationContext() */ 247 private boolean mIsConfigurationBasedContext; 248 249 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 250 private final int mFlags; 251 252 @UnsupportedAppUsage 253 private Context mOuterContext; 254 @UnsupportedAppUsage 255 private int mThemeResource = 0; 256 @UnsupportedAppUsage 257 private Resources.Theme mTheme = null; 258 @UnsupportedAppUsage 259 private PackageManager mPackageManager; 260 private Context mReceiverRestrictedContext = null; 261 262 // The name of the split this Context is representing. May be null. 263 private @Nullable String mSplitName = null; 264 265 private @Nullable AutofillClient mAutofillClient = null; 266 private @Nullable AutofillOptions mAutofillOptions; 267 268 private ContentCaptureOptions mContentCaptureOptions = null; 269 270 private final Object mSync = new Object(); 271 /** 272 * Indicates this {@link Context} can not handle UI components properly and is not associated 273 * with a {@link Display} instance. 274 */ 275 private static final int CONTEXT_TYPE_NON_UI = 0; 276 /** 277 * Indicates this {@link Context} is associated with a {@link Display} instance but should not 278 * be handled UI components properly because it doesn't receive configuration changes 279 * regardless of display property updates. 280 */ 281 private static final int CONTEXT_TYPE_DISPLAY_CONTEXT = 1; 282 /** 283 * Indicates this {@link Context} is an {@link Activity} or {@link Activity} derived 284 * {@link Context}. 285 */ 286 private static final int CONTEXT_TYPE_ACTIVITY = 2; 287 /** 288 * Indicates this {@link Context} is a {@link WindowContext} or {@link WindowContext} derived 289 * {@link Context}. 290 */ 291 private static final int CONTEXT_TYPE_WINDOW_CONTEXT = 3; 292 293 // TODO(b/170369943): Remove after WindowContext migration 294 /** 295 * Indicates this {@link Context} is created from {@link #createSystemContext(ActivityThread)} 296 * or {@link #createSystemUiContext(ContextImpl, int)} or any {@link Context} that system UI 297 * uses. 298 */ 299 private static final int CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI = 4; 300 301 @IntDef(prefix = "CONTEXT_TYPE_", value = { 302 CONTEXT_TYPE_NON_UI, 303 CONTEXT_TYPE_DISPLAY_CONTEXT, 304 CONTEXT_TYPE_ACTIVITY, 305 CONTEXT_TYPE_WINDOW_CONTEXT, 306 CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI 307 }) 308 @Retention(RetentionPolicy.SOURCE) 309 private @interface ContextType {} 310 311 @ContextType 312 private int mContextType; 313 314 /** 315 * {@code true} to indicate that the {@link Context} owns the {@link #getWindowContextToken()} 316 * and is responsible for detaching the token when the Context is released. 317 * 318 * @see #finalize() 319 */ 320 private boolean mOwnsToken = false; 321 322 @GuardedBy("mSync") 323 private File mDatabasesDir; 324 @GuardedBy("mSync") 325 @UnsupportedAppUsage 326 private File mPreferencesDir; 327 @GuardedBy("mSync") 328 private File mFilesDir; 329 @GuardedBy("mSync") 330 private File mCratesDir; 331 @GuardedBy("mSync") 332 private File mNoBackupFilesDir; 333 @GuardedBy("mSync") 334 private File mCacheDir; 335 @GuardedBy("mSync") 336 private File mCodeCacheDir; 337 338 // The system service cache for the system services that are cached per-ContextImpl. 339 @UnsupportedAppUsage 340 final Object[] mServiceCache = SystemServiceRegistry.createServiceCache(); 341 342 static final int STATE_UNINITIALIZED = 0; 343 static final int STATE_INITIALIZING = 1; 344 static final int STATE_READY = 2; 345 static final int STATE_NOT_FOUND = 3; 346 347 /** @hide */ 348 @IntDef(prefix = { "STATE_" }, value = { 349 STATE_UNINITIALIZED, 350 STATE_INITIALIZING, 351 STATE_READY, 352 STATE_NOT_FOUND, 353 }) 354 @Retention(RetentionPolicy.SOURCE) 355 @interface ServiceInitializationState {} 356 357 /** 358 * Initialization state for each service. Any of {@link #STATE_UNINITIALIZED}, 359 * {@link #STATE_INITIALIZING} or {@link #STATE_READY}, 360 */ 361 @ServiceInitializationState 362 final int[] mServiceInitializationStateArray = new int[mServiceCache.length]; 363 364 @UnsupportedAppUsage getImpl(Context context)365 static ContextImpl getImpl(Context context) { 366 Context nextContext; 367 while ((context instanceof ContextWrapper) && 368 (nextContext=((ContextWrapper)context).getBaseContext()) != null) { 369 context = nextContext; 370 } 371 return (ContextImpl)context; 372 } 373 374 @Override getAssets()375 public AssetManager getAssets() { 376 return getResources().getAssets(); 377 } 378 379 @Override getResources()380 public Resources getResources() { 381 return mResources; 382 } 383 384 @Override getPackageManager()385 public PackageManager getPackageManager() { 386 if (mPackageManager != null) { 387 return mPackageManager; 388 } 389 390 final IPackageManager pm = ActivityThread.getPackageManager(); 391 if (pm != null) { 392 // Doesn't matter if we make more than one instance. 393 return (mPackageManager = new ApplicationPackageManager(this, pm)); 394 } 395 396 return null; 397 } 398 399 @Override getContentResolver()400 public ContentResolver getContentResolver() { 401 return mContentResolver; 402 } 403 404 @Override getMainLooper()405 public Looper getMainLooper() { 406 return mMainThread.getLooper(); 407 } 408 409 @Override getMainExecutor()410 public Executor getMainExecutor() { 411 return mMainThread.getExecutor(); 412 } 413 414 @Override getApplicationContext()415 public Context getApplicationContext() { 416 return (mPackageInfo != null) ? 417 mPackageInfo.getApplication() : mMainThread.getApplication(); 418 } 419 420 @Override setTheme(int resId)421 public void setTheme(int resId) { 422 synchronized (mSync) { 423 if (mThemeResource != resId) { 424 mThemeResource = resId; 425 initializeTheme(); 426 } 427 } 428 } 429 430 @Override getThemeResId()431 public int getThemeResId() { 432 synchronized (mSync) { 433 return mThemeResource; 434 } 435 } 436 437 @Override getTheme()438 public Resources.Theme getTheme() { 439 synchronized (mSync) { 440 if (mTheme != null) { 441 return mTheme; 442 } 443 444 mThemeResource = Resources.selectDefaultTheme(mThemeResource, 445 getOuterContext().getApplicationInfo().targetSdkVersion); 446 initializeTheme(); 447 448 return mTheme; 449 } 450 } 451 initializeTheme()452 private void initializeTheme() { 453 if (mTheme == null) { 454 mTheme = mResources.newTheme(); 455 } 456 mTheme.applyStyle(mThemeResource, true); 457 } 458 459 @Override getClassLoader()460 public ClassLoader getClassLoader() { 461 return mClassLoader != null ? mClassLoader : (mPackageInfo != null ? mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader()); 462 } 463 464 @Override getPackageName()465 public String getPackageName() { 466 if (mPackageInfo != null) { 467 return mPackageInfo.getPackageName(); 468 } 469 // No mPackageInfo means this is a Context for the system itself, 470 // and this here is its name. 471 return "android"; 472 } 473 474 /** @hide */ 475 @Override getBasePackageName()476 public String getBasePackageName() { 477 return mBasePackageName != null ? mBasePackageName : getPackageName(); 478 } 479 480 /** @hide */ 481 @Override getOpPackageName()482 public String getOpPackageName() { 483 return mAttributionSource.getPackageName(); 484 } 485 486 /** @hide */ 487 @Override getAttributionTag()488 public @Nullable String getAttributionTag() { 489 return mAttributionSource.getAttributionTag(); 490 } 491 492 @Override getParams()493 public @Nullable ContextParams getParams() { 494 return mParams; 495 } 496 497 @Override getAttributionSource()498 public @NonNull AttributionSource getAttributionSource() { 499 return mAttributionSource; 500 } 501 502 @Override getApplicationInfo()503 public ApplicationInfo getApplicationInfo() { 504 if (mPackageInfo != null) { 505 return mPackageInfo.getApplicationInfo(); 506 } 507 throw new RuntimeException("Not supported in system context"); 508 } 509 510 @Override getPackageResourcePath()511 public String getPackageResourcePath() { 512 if (mPackageInfo != null) { 513 return mPackageInfo.getResDir(); 514 } 515 throw new RuntimeException("Not supported in system context"); 516 } 517 518 @Override getPackageCodePath()519 public String getPackageCodePath() { 520 if (mPackageInfo != null) { 521 return mPackageInfo.getAppDir(); 522 } 523 throw new RuntimeException("Not supported in system context"); 524 } 525 526 @Override getSharedPreferences(String name, int mode)527 public SharedPreferences getSharedPreferences(String name, int mode) { 528 // At least one application in the world actually passes in a null 529 // name. This happened to work because when we generated the file name 530 // we would stringify it to "null.xml". Nice. 531 if (mPackageInfo.getApplicationInfo().targetSdkVersion < 532 Build.VERSION_CODES.KITKAT) { 533 if (name == null) { 534 name = "null"; 535 } 536 } 537 538 File file; 539 synchronized (ContextImpl.class) { 540 if (mSharedPrefsPaths == null) { 541 mSharedPrefsPaths = new ArrayMap<>(); 542 } 543 file = mSharedPrefsPaths.get(name); 544 if (file == null) { 545 file = getSharedPreferencesPath(name); 546 mSharedPrefsPaths.put(name, file); 547 } 548 } 549 return getSharedPreferences(file, mode); 550 } 551 552 @Override getSharedPreferences(File file, int mode)553 public SharedPreferences getSharedPreferences(File file, int mode) { 554 SharedPreferencesImpl sp; 555 synchronized (ContextImpl.class) { 556 final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked(); 557 sp = cache.get(file); 558 if (sp == null) { 559 checkMode(mode); 560 if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) { 561 if (isCredentialProtectedStorage() 562 && !getSystemService(UserManager.class) 563 .isUserUnlockingOrUnlocked(UserHandle.myUserId())) { 564 throw new IllegalStateException("SharedPreferences in credential encrypted " 565 + "storage are not available until after user is unlocked"); 566 } 567 } 568 sp = new SharedPreferencesImpl(file, mode); 569 cache.put(file, sp); 570 return sp; 571 } 572 } 573 if ((mode & Context.MODE_MULTI_PROCESS) != 0 || 574 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { 575 // If somebody else (some other process) changed the prefs 576 // file behind our back, we reload it. This has been the 577 // historical (if undocumented) behavior. 578 sp.startReloadIfChangedUnexpectedly(); 579 } 580 return sp; 581 } 582 583 @GuardedBy("ContextImpl.class") getSharedPreferencesCacheLocked()584 private ArrayMap<File, SharedPreferencesImpl> getSharedPreferencesCacheLocked() { 585 if (sSharedPrefsCache == null) { 586 sSharedPrefsCache = new ArrayMap<>(); 587 } 588 589 final String packageName = getPackageName(); 590 ArrayMap<File, SharedPreferencesImpl> packagePrefs = sSharedPrefsCache.get(packageName); 591 if (packagePrefs == null) { 592 packagePrefs = new ArrayMap<>(); 593 sSharedPrefsCache.put(packageName, packagePrefs); 594 } 595 596 return packagePrefs; 597 } 598 599 @Override reloadSharedPreferences()600 public void reloadSharedPreferences() { 601 // Build the list of all per-context impls (i.e. caches) we know about 602 ArrayList<SharedPreferencesImpl> spImpls = new ArrayList<>(); 603 synchronized (ContextImpl.class) { 604 final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked(); 605 for (int i = 0; i < cache.size(); i++) { 606 final SharedPreferencesImpl sp = cache.valueAt(i); 607 if (sp != null) { 608 spImpls.add(sp); 609 } 610 } 611 } 612 613 // Issue the reload outside the cache lock 614 for (int i = 0; i < spImpls.size(); i++) { 615 spImpls.get(i).startReloadIfChangedUnexpectedly(); 616 } 617 } 618 619 /** 620 * Try our best to migrate all files from source to target that match 621 * requested prefix. 622 * 623 * @return the number of files moved, or -1 if there was trouble. 624 */ moveFiles(File sourceDir, File targetDir, final String prefix)625 private static int moveFiles(File sourceDir, File targetDir, final String prefix) { 626 final File[] sourceFiles = FileUtils.listFilesOrEmpty(sourceDir, new FilenameFilter() { 627 @Override 628 public boolean accept(File dir, String name) { 629 return name.startsWith(prefix); 630 } 631 }); 632 633 int res = 0; 634 for (File sourceFile : sourceFiles) { 635 final File targetFile = new File(targetDir, sourceFile.getName()); 636 Log.d(TAG, "Migrating " + sourceFile + " to " + targetFile); 637 try { 638 FileUtils.copyFileOrThrow(sourceFile, targetFile); 639 FileUtils.copyPermissions(sourceFile, targetFile); 640 if (!sourceFile.delete()) { 641 throw new IOException("Failed to clean up " + sourceFile); 642 } 643 if (res != -1) { 644 res++; 645 } 646 } catch (IOException e) { 647 Log.w(TAG, "Failed to migrate " + sourceFile + ": " + e); 648 res = -1; 649 } 650 } 651 return res; 652 } 653 654 @Override moveSharedPreferencesFrom(Context sourceContext, String name)655 public boolean moveSharedPreferencesFrom(Context sourceContext, String name) { 656 synchronized (ContextImpl.class) { 657 final File source = sourceContext.getSharedPreferencesPath(name); 658 final File target = getSharedPreferencesPath(name); 659 660 final int res = moveFiles(source.getParentFile(), target.getParentFile(), 661 source.getName()); 662 if (res > 0) { 663 // We moved at least one file, so evict any in-memory caches for 664 // either location 665 final ArrayMap<File, SharedPreferencesImpl> cache = 666 getSharedPreferencesCacheLocked(); 667 cache.remove(source); 668 cache.remove(target); 669 } 670 return res != -1; 671 } 672 } 673 674 @Override deleteSharedPreferences(String name)675 public boolean deleteSharedPreferences(String name) { 676 synchronized (ContextImpl.class) { 677 final File prefs = getSharedPreferencesPath(name); 678 final File prefsBackup = SharedPreferencesImpl.makeBackupFile(prefs); 679 680 // Evict any in-memory caches 681 final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked(); 682 cache.remove(prefs); 683 684 prefs.delete(); 685 prefsBackup.delete(); 686 687 // We failed if files are still lingering 688 return !(prefs.exists() || prefsBackup.exists()); 689 } 690 } 691 692 @UnsupportedAppUsage getPreferencesDir()693 private File getPreferencesDir() { 694 synchronized (mSync) { 695 if (mPreferencesDir == null) { 696 mPreferencesDir = new File(getDataDir(), "shared_prefs"); 697 } 698 return ensurePrivateDirExists(mPreferencesDir); 699 } 700 } 701 702 @Override openFileInput(String name)703 public FileInputStream openFileInput(String name) 704 throws FileNotFoundException { 705 File f = makeFilename(getFilesDir(), name); 706 return new FileInputStream(f); 707 } 708 709 @Override openFileOutput(String name, int mode)710 public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException { 711 checkMode(mode); 712 final boolean append = (mode&MODE_APPEND) != 0; 713 File f = makeFilename(getFilesDir(), name); 714 try { 715 FileOutputStream fos = new FileOutputStream(f, append); 716 setFilePermissionsFromMode(f.getPath(), mode, 0); 717 return fos; 718 } catch (FileNotFoundException e) { 719 } 720 721 File parent = f.getParentFile(); 722 parent.mkdir(); 723 FileUtils.setPermissions( 724 parent.getPath(), 725 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 726 -1, -1); 727 FileOutputStream fos = new FileOutputStream(f, append); 728 setFilePermissionsFromMode(f.getPath(), mode, 0); 729 return fos; 730 } 731 732 @Override deleteFile(String name)733 public boolean deleteFile(String name) { 734 File f = makeFilename(getFilesDir(), name); 735 return f.delete(); 736 } 737 738 /** 739 * Common-path handling of app data dir creation 740 */ ensurePrivateDirExists(File file)741 private static File ensurePrivateDirExists(File file) { 742 return ensurePrivateDirExists(file, 0771, -1, null); 743 } 744 ensurePrivateCacheDirExists(File file, String xattr)745 private static File ensurePrivateCacheDirExists(File file, String xattr) { 746 final int gid = UserHandle.getCacheAppGid(Process.myUid()); 747 return ensurePrivateDirExists(file, 02771, gid, xattr); 748 } 749 ensurePrivateDirExists(File file, int mode, int gid, String xattr)750 private static File ensurePrivateDirExists(File file, int mode, int gid, String xattr) { 751 if (!file.exists()) { 752 final String path = file.getAbsolutePath(); 753 try { 754 Os.mkdir(path, mode); 755 Os.chmod(path, mode); 756 if (gid != -1) { 757 Os.chown(path, -1, gid); 758 } 759 } catch (ErrnoException e) { 760 if (e.errno == OsConstants.EEXIST) { 761 // We must have raced with someone; that's okay 762 } else { 763 Log.w(TAG, "Failed to ensure " + file + ": " + e.getMessage()); 764 } 765 } 766 767 if (xattr != null) { 768 try { 769 final StructStat stat = Os.stat(file.getAbsolutePath()); 770 final byte[] value = new byte[8]; 771 Memory.pokeLong(value, 0, stat.st_ino, ByteOrder.nativeOrder()); 772 Os.setxattr(file.getParentFile().getAbsolutePath(), xattr, value, 0); 773 } catch (ErrnoException e) { 774 Log.w(TAG, "Failed to update " + xattr + ": " + e.getMessage()); 775 } 776 } 777 } 778 return file; 779 } 780 781 @Override getFilesDir()782 public File getFilesDir() { 783 synchronized (mSync) { 784 if (mFilesDir == null) { 785 mFilesDir = new File(getDataDir(), "files"); 786 } 787 return ensurePrivateDirExists(mFilesDir); 788 } 789 } 790 791 @Override getCrateDir(@onNull String crateId)792 public File getCrateDir(@NonNull String crateId) { 793 Preconditions.checkArgument(FileUtils.isValidExtFilename(crateId), "invalidated crateId"); 794 final Path cratesRootPath = getDataDir().toPath().resolve("crates"); 795 final Path absoluteNormalizedCratePath = cratesRootPath.resolve(crateId) 796 .toAbsolutePath().normalize(); 797 798 synchronized (mSync) { 799 if (mCratesDir == null) { 800 mCratesDir = cratesRootPath.toFile(); 801 } 802 ensurePrivateDirExists(mCratesDir); 803 } 804 805 File cratedDir = absoluteNormalizedCratePath.toFile(); 806 return ensurePrivateDirExists(cratedDir); 807 } 808 809 @Override getNoBackupFilesDir()810 public File getNoBackupFilesDir() { 811 synchronized (mSync) { 812 if (mNoBackupFilesDir == null) { 813 mNoBackupFilesDir = new File(getDataDir(), "no_backup"); 814 } 815 return ensurePrivateDirExists(mNoBackupFilesDir); 816 } 817 } 818 819 @Override getExternalFilesDir(String type)820 public File getExternalFilesDir(String type) { 821 // Operates on primary external storage 822 final File[] dirs = getExternalFilesDirs(type); 823 return (dirs != null && dirs.length > 0) ? dirs[0] : null; 824 } 825 826 @Override getExternalFilesDirs(String type)827 public File[] getExternalFilesDirs(String type) { 828 synchronized (mSync) { 829 File[] dirs = Environment.buildExternalStorageAppFilesDirs(getPackageName()); 830 if (type != null) { 831 dirs = Environment.buildPaths(dirs, type); 832 } 833 return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */); 834 } 835 } 836 837 @Override getObbDir()838 public File getObbDir() { 839 // Operates on primary external storage 840 final File[] dirs = getObbDirs(); 841 return (dirs != null && dirs.length > 0) ? dirs[0] : null; 842 } 843 844 @Override getObbDirs()845 public File[] getObbDirs() { 846 synchronized (mSync) { 847 File[] dirs = Environment.buildExternalStorageAppObbDirs(getPackageName()); 848 return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */); 849 } 850 } 851 852 @Override getCacheDir()853 public File getCacheDir() { 854 synchronized (mSync) { 855 if (mCacheDir == null) { 856 mCacheDir = new File(getDataDir(), "cache"); 857 } 858 return ensurePrivateCacheDirExists(mCacheDir, XATTR_INODE_CACHE); 859 } 860 } 861 862 @Override getCodeCacheDir()863 public File getCodeCacheDir() { 864 synchronized (mSync) { 865 if (mCodeCacheDir == null) { 866 mCodeCacheDir = getCodeCacheDirBeforeBind(getDataDir()); 867 } 868 return ensurePrivateCacheDirExists(mCodeCacheDir, XATTR_INODE_CODE_CACHE); 869 } 870 } 871 872 /** 873 * Helper for getting code-cache dir potentially before application bind. 874 * 875 * @hide 876 */ getCodeCacheDirBeforeBind(File dataDir)877 static File getCodeCacheDirBeforeBind(File dataDir) { 878 return new File(dataDir, "code_cache"); 879 } 880 881 @Override getExternalCacheDir()882 public File getExternalCacheDir() { 883 // Operates on primary external storage 884 final File[] dirs = getExternalCacheDirs(); 885 return (dirs != null && dirs.length > 0) ? dirs[0] : null; 886 } 887 888 @Override getExternalCacheDirs()889 public File[] getExternalCacheDirs() { 890 synchronized (mSync) { 891 File[] dirs = Environment.buildExternalStorageAppCacheDirs(getPackageName()); 892 // We don't try to create cache directories in-process, because they need special 893 // setup for accurate quota tracking. This ensures the cache dirs are always 894 // created through StorageManagerService. 895 return ensureExternalDirsExistOrFilter(dirs, false /* tryCreateInProcess */); 896 } 897 } 898 899 @Override getExternalMediaDirs()900 public File[] getExternalMediaDirs() { 901 synchronized (mSync) { 902 File[] dirs = Environment.buildExternalStorageAppMediaDirs(getPackageName()); 903 return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */); 904 } 905 } 906 907 /** 908 * @hide 909 */ 910 @Nullable 911 @Override getPreloadsFileCache()912 public File getPreloadsFileCache() { 913 return Environment.getDataPreloadsFileCacheDirectory(getPackageName()); 914 } 915 916 @Override getFileStreamPath(String name)917 public File getFileStreamPath(String name) { 918 return makeFilename(getFilesDir(), name); 919 } 920 921 @Override getSharedPreferencesPath(String name)922 public File getSharedPreferencesPath(String name) { 923 return makeFilename(getPreferencesDir(), name + ".xml"); 924 } 925 926 @Override fileList()927 public String[] fileList() { 928 return FileUtils.listOrEmpty(getFilesDir()); 929 } 930 931 @Override openOrCreateDatabase(String name, int mode, CursorFactory factory)932 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { 933 return openOrCreateDatabase(name, mode, factory, null); 934 } 935 936 @Override openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler)937 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, 938 DatabaseErrorHandler errorHandler) { 939 checkMode(mode); 940 File f = getDatabasePath(name); 941 int flags = SQLiteDatabase.CREATE_IF_NECESSARY; 942 if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) { 943 flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING; 944 } 945 if ((mode & MODE_NO_LOCALIZED_COLLATORS) != 0) { 946 flags |= SQLiteDatabase.NO_LOCALIZED_COLLATORS; 947 } 948 SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler); 949 setFilePermissionsFromMode(f.getPath(), mode, 0); 950 return db; 951 } 952 953 @Override moveDatabaseFrom(Context sourceContext, String name)954 public boolean moveDatabaseFrom(Context sourceContext, String name) { 955 synchronized (ContextImpl.class) { 956 final File source = sourceContext.getDatabasePath(name); 957 final File target = getDatabasePath(name); 958 return moveFiles(source.getParentFile(), target.getParentFile(), 959 source.getName()) != -1; 960 } 961 } 962 963 @Override deleteDatabase(String name)964 public boolean deleteDatabase(String name) { 965 try { 966 File f = getDatabasePath(name); 967 return SQLiteDatabase.deleteDatabase(f); 968 } catch (Exception e) { 969 } 970 return false; 971 } 972 973 @Override getDatabasePath(String name)974 public File getDatabasePath(String name) { 975 File dir; 976 File f; 977 978 if (name.charAt(0) == File.separatorChar) { 979 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar)); 980 dir = new File(dirPath); 981 name = name.substring(name.lastIndexOf(File.separatorChar)); 982 f = new File(dir, name); 983 984 if (!dir.isDirectory() && dir.mkdir()) { 985 FileUtils.setPermissions(dir.getPath(), 986 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 987 -1, -1); 988 } 989 } else { 990 dir = getDatabasesDir(); 991 f = makeFilename(dir, name); 992 } 993 994 return f; 995 } 996 997 @Override databaseList()998 public String[] databaseList() { 999 return FileUtils.listOrEmpty(getDatabasesDir()); 1000 } 1001 getDatabasesDir()1002 private File getDatabasesDir() { 1003 synchronized (mSync) { 1004 if (mDatabasesDir == null) { 1005 if ("android".equals(getPackageName())) { 1006 mDatabasesDir = new File("/data/system"); 1007 } else { 1008 mDatabasesDir = new File(getDataDir(), "databases"); 1009 } 1010 } 1011 return ensurePrivateDirExists(mDatabasesDir); 1012 } 1013 } 1014 1015 @Override 1016 @Deprecated getWallpaper()1017 public Drawable getWallpaper() { 1018 return getWallpaperManager().getDrawable(); 1019 } 1020 1021 @Override 1022 @Deprecated peekWallpaper()1023 public Drawable peekWallpaper() { 1024 return getWallpaperManager().peekDrawable(); 1025 } 1026 1027 @Override 1028 @Deprecated getWallpaperDesiredMinimumWidth()1029 public int getWallpaperDesiredMinimumWidth() { 1030 return getWallpaperManager().getDesiredMinimumWidth(); 1031 } 1032 1033 @Override 1034 @Deprecated getWallpaperDesiredMinimumHeight()1035 public int getWallpaperDesiredMinimumHeight() { 1036 return getWallpaperManager().getDesiredMinimumHeight(); 1037 } 1038 1039 @Override 1040 @Deprecated setWallpaper(Bitmap bitmap)1041 public void setWallpaper(Bitmap bitmap) throws IOException { 1042 getWallpaperManager().setBitmap(bitmap); 1043 } 1044 1045 @Override 1046 @Deprecated setWallpaper(InputStream data)1047 public void setWallpaper(InputStream data) throws IOException { 1048 getWallpaperManager().setStream(data); 1049 } 1050 1051 @Override 1052 @Deprecated clearWallpaper()1053 public void clearWallpaper() throws IOException { 1054 getWallpaperManager().clear(); 1055 } 1056 getWallpaperManager()1057 private WallpaperManager getWallpaperManager() { 1058 return getSystemService(WallpaperManager.class); 1059 } 1060 1061 @Override startActivity(Intent intent)1062 public void startActivity(Intent intent) { 1063 warnIfCallingFromSystemProcess(); 1064 startActivity(intent, null); 1065 } 1066 1067 /** @hide */ 1068 @Override startActivityAsUser(Intent intent, UserHandle user)1069 public void startActivityAsUser(Intent intent, UserHandle user) { 1070 startActivityAsUser(intent, null, user); 1071 } 1072 1073 @Override startActivity(Intent intent, Bundle options)1074 public void startActivity(Intent intent, Bundle options) { 1075 warnIfCallingFromSystemProcess(); 1076 1077 // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is 1078 // generally not allowed, except if the caller specifies the task id the activity should 1079 // be launched in. A bug was existed between N and O-MR1 which allowed this to work. We 1080 // maintain this for backwards compatibility. 1081 final int targetSdkVersion = getApplicationInfo().targetSdkVersion; 1082 1083 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 1084 && (targetSdkVersion < Build.VERSION_CODES.N 1085 || targetSdkVersion >= Build.VERSION_CODES.P) 1086 && (options == null 1087 || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) { 1088 throw new AndroidRuntimeException( 1089 "Calling startActivity() from outside of an Activity " 1090 + " context requires the FLAG_ACTIVITY_NEW_TASK flag." 1091 + " Is this really what you want?"); 1092 } 1093 mMainThread.getInstrumentation().execStartActivity( 1094 getOuterContext(), mMainThread.getApplicationThread(), null, 1095 (Activity) null, intent, -1, options); 1096 } 1097 1098 /** @hide */ 1099 @Override startActivityAsUser(Intent intent, Bundle options, UserHandle user)1100 public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { 1101 try { 1102 ActivityTaskManager.getService().startActivityAsUser( 1103 mMainThread.getApplicationThread(), getOpPackageName(), getAttributionTag(), 1104 intent, intent.resolveTypeIfNeeded(getContentResolver()), 1105 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, 1106 user.getIdentifier()); 1107 } catch (RemoteException e) { 1108 throw e.rethrowFromSystemServer(); 1109 } 1110 } 1111 1112 @Override startActivities(Intent[] intents)1113 public void startActivities(Intent[] intents) { 1114 warnIfCallingFromSystemProcess(); 1115 startActivities(intents, null); 1116 } 1117 1118 /** @hide */ 1119 @Override startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle)1120 public int startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) { 1121 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1122 throw new AndroidRuntimeException( 1123 "Calling startActivities() from outside of an Activity " 1124 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." 1125 + " Is this really what you want?"); 1126 } 1127 return mMainThread.getInstrumentation().execStartActivitiesAsUser( 1128 getOuterContext(), mMainThread.getApplicationThread(), null, 1129 (Activity) null, intents, options, userHandle.getIdentifier()); 1130 } 1131 1132 @Override startActivities(Intent[] intents, Bundle options)1133 public void startActivities(Intent[] intents, Bundle options) { 1134 warnIfCallingFromSystemProcess(); 1135 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 1136 throw new AndroidRuntimeException( 1137 "Calling startActivities() from outside of an Activity " 1138 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." 1139 + " Is this really what you want?"); 1140 } 1141 mMainThread.getInstrumentation().execStartActivities( 1142 getOuterContext(), mMainThread.getApplicationThread(), null, 1143 (Activity) null, intents, options); 1144 } 1145 1146 @Override startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)1147 public void startIntentSender(IntentSender intent, 1148 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 1149 throws IntentSender.SendIntentException { 1150 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null); 1151 } 1152 1153 @Override startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options)1154 public void startIntentSender(IntentSender intent, Intent fillInIntent, 1155 int flagsMask, int flagsValues, int extraFlags, Bundle options) 1156 throws IntentSender.SendIntentException { 1157 try { 1158 String resolvedType = null; 1159 if (fillInIntent != null) { 1160 fillInIntent.migrateExtraStreamToClipData(this); 1161 fillInIntent.prepareToLeaveProcess(this); 1162 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 1163 } 1164 int result = ActivityTaskManager.getService() 1165 .startActivityIntentSender(mMainThread.getApplicationThread(), 1166 intent != null ? intent.getTarget() : null, 1167 intent != null ? intent.getWhitelistToken() : null, 1168 fillInIntent, resolvedType, null, null, 1169 0, flagsMask, flagsValues, options); 1170 if (result == ActivityManager.START_CANCELED) { 1171 throw new IntentSender.SendIntentException(); 1172 } 1173 Instrumentation.checkStartActivityResult(result, null); 1174 } catch (RemoteException e) { 1175 throw e.rethrowFromSystemServer(); 1176 } 1177 } 1178 1179 @Override sendBroadcast(Intent intent)1180 public void sendBroadcast(Intent intent) { 1181 warnIfCallingFromSystemProcess(); 1182 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1183 try { 1184 intent.prepareToLeaveProcess(this); 1185 ActivityManager.getService().broadcastIntentWithFeature( 1186 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1187 null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, 1188 AppOpsManager.OP_NONE, null, false, false, getUserId()); 1189 } catch (RemoteException e) { 1190 throw e.rethrowFromSystemServer(); 1191 } 1192 } 1193 1194 @Override sendBroadcast(Intent intent, String receiverPermission)1195 public void sendBroadcast(Intent intent, String receiverPermission) { 1196 warnIfCallingFromSystemProcess(); 1197 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1198 String[] receiverPermissions = receiverPermission == null ? null 1199 : new String[] {receiverPermission}; 1200 try { 1201 intent.prepareToLeaveProcess(this); 1202 ActivityManager.getService().broadcastIntentWithFeature( 1203 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1204 null, Activity.RESULT_OK, null, null, receiverPermissions, 1205 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, 1206 getUserId()); 1207 } catch (RemoteException e) { 1208 throw e.rethrowFromSystemServer(); 1209 } 1210 } 1211 1212 @Override sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions)1213 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 1214 warnIfCallingFromSystemProcess(); 1215 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1216 try { 1217 intent.prepareToLeaveProcess(this); 1218 ActivityManager.getService().broadcastIntentWithFeature( 1219 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1220 null, Activity.RESULT_OK, null, null, receiverPermissions, 1221 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, 1222 getUserId()); 1223 } catch (RemoteException e) { 1224 throw e.rethrowFromSystemServer(); 1225 } 1226 } 1227 1228 @Override sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, Bundle options)1229 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, 1230 Bundle options) { 1231 warnIfCallingFromSystemProcess(); 1232 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1233 try { 1234 intent.prepareToLeaveProcess(this); 1235 ActivityManager.getService().broadcastIntentWithFeature( 1236 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1237 null, Activity.RESULT_OK, null, null, receiverPermissions, 1238 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, 1239 getUserId()); 1240 } catch (RemoteException e) { 1241 throw e.rethrowFromSystemServer(); 1242 } 1243 } 1244 1245 @Override sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions)1246 public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, 1247 String[] receiverPermissions) { 1248 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1249 try { 1250 intent.prepareToLeaveProcess(this); 1251 ActivityManager.getService().broadcastIntentWithFeature( 1252 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1253 null, Activity.RESULT_OK, null, null, receiverPermissions, 1254 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, false, false, 1255 user.getIdentifier()); 1256 } catch (RemoteException e) { 1257 throw e.rethrowFromSystemServer(); 1258 } 1259 } 1260 1261 @Override sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, String[] excludedPermissions)1262 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, 1263 String[] excludedPermissions) { 1264 warnIfCallingFromSystemProcess(); 1265 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1266 try { 1267 intent.prepareToLeaveProcess(this); 1268 ActivityManager.getService().broadcastIntentWithFeature( 1269 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1270 null, Activity.RESULT_OK, null, null, receiverPermissions, excludedPermissions, 1271 AppOpsManager.OP_NONE, null, false, false, getUserId()); 1272 } catch (RemoteException e) { 1273 throw e.rethrowFromSystemServer(); 1274 } 1275 } 1276 1277 @Override sendBroadcast(Intent intent, String receiverPermission, Bundle options)1278 public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { 1279 warnIfCallingFromSystemProcess(); 1280 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1281 String[] receiverPermissions = receiverPermission == null ? null 1282 : new String[] {receiverPermission}; 1283 try { 1284 intent.prepareToLeaveProcess(this); 1285 ActivityManager.getService().broadcastIntentWithFeature( 1286 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1287 null, Activity.RESULT_OK, null, null, receiverPermissions, 1288 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, 1289 getUserId()); 1290 } catch (RemoteException e) { 1291 throw e.rethrowFromSystemServer(); 1292 } 1293 } 1294 1295 @Override sendBroadcast(Intent intent, String receiverPermission, int appOp)1296 public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { 1297 warnIfCallingFromSystemProcess(); 1298 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1299 String[] receiverPermissions = receiverPermission == null ? null 1300 : new String[] {receiverPermission}; 1301 try { 1302 intent.prepareToLeaveProcess(this); 1303 ActivityManager.getService().broadcastIntentWithFeature( 1304 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1305 null, Activity.RESULT_OK, null, null, receiverPermissions, 1306 null /*excludedPermissions=*/, appOp, null, false, false, getUserId()); 1307 } catch (RemoteException e) { 1308 throw e.rethrowFromSystemServer(); 1309 } 1310 } 1311 1312 @Override sendOrderedBroadcast(Intent intent, String receiverPermission)1313 public void sendOrderedBroadcast(Intent intent, String receiverPermission) { 1314 warnIfCallingFromSystemProcess(); 1315 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1316 String[] receiverPermissions = receiverPermission == null ? null 1317 : new String[] {receiverPermission}; 1318 try { 1319 intent.prepareToLeaveProcess(this); 1320 ActivityManager.getService().broadcastIntentWithFeature( 1321 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1322 null, Activity.RESULT_OK, null, null, receiverPermissions, 1323 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, false, 1324 getUserId()); 1325 } catch (RemoteException e) { 1326 throw e.rethrowFromSystemServer(); 1327 } 1328 } 1329 1330 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1331 public void sendOrderedBroadcast(Intent intent, 1332 String receiverPermission, BroadcastReceiver resultReceiver, 1333 Handler scheduler, int initialCode, String initialData, 1334 Bundle initialExtras) { 1335 sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE, 1336 resultReceiver, scheduler, initialCode, initialData, initialExtras, null); 1337 } 1338 1339 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1340 public void sendOrderedBroadcast(Intent intent, 1341 String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, 1342 Handler scheduler, int initialCode, String initialData, 1343 Bundle initialExtras) { 1344 sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE, 1345 resultReceiver, scheduler, initialCode, initialData, initialExtras, options); 1346 } 1347 1348 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1349 public void sendOrderedBroadcast(Intent intent, 1350 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 1351 Handler scheduler, int initialCode, String initialData, 1352 Bundle initialExtras) { 1353 sendOrderedBroadcast(intent, receiverPermission, appOp, 1354 resultReceiver, scheduler, initialCode, initialData, initialExtras, null); 1355 } 1356 sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras, Bundle options)1357 void sendOrderedBroadcast(Intent intent, 1358 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 1359 Handler scheduler, int initialCode, String initialData, 1360 Bundle initialExtras, Bundle options) { 1361 warnIfCallingFromSystemProcess(); 1362 IIntentReceiver rd = null; 1363 if (resultReceiver != null) { 1364 if (mPackageInfo != null) { 1365 if (scheduler == null) { 1366 scheduler = mMainThread.getHandler(); 1367 } 1368 rd = mPackageInfo.getReceiverDispatcher( 1369 resultReceiver, getOuterContext(), scheduler, 1370 mMainThread.getInstrumentation(), false); 1371 } else { 1372 if (scheduler == null) { 1373 scheduler = mMainThread.getHandler(); 1374 } 1375 rd = new LoadedApk.ReceiverDispatcher( 1376 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 1377 } 1378 } 1379 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1380 String[] receiverPermissions = receiverPermission == null ? null 1381 : new String[] {receiverPermission}; 1382 try { 1383 intent.prepareToLeaveProcess(this); 1384 ActivityManager.getService().broadcastIntentWithFeature( 1385 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1386 rd, initialCode, initialData, initialExtras, receiverPermissions, 1387 null /*excludedPermissions=*/, appOp, options, true, false, getUserId()); 1388 } catch (RemoteException e) { 1389 throw e.rethrowFromSystemServer(); 1390 } 1391 } 1392 1393 @Override sendBroadcastAsUser(Intent intent, UserHandle user)1394 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 1395 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1396 try { 1397 intent.prepareToLeaveProcess(this); 1398 ActivityManager.getService().broadcastIntentWithFeature( 1399 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1400 null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, 1401 AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); 1402 } catch (RemoteException e) { 1403 throw e.rethrowFromSystemServer(); 1404 } 1405 } 1406 1407 @Override sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)1408 public void sendBroadcastAsUser(Intent intent, UserHandle user, 1409 String receiverPermission) { 1410 sendBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE); 1411 } 1412 1413 @Override sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, Bundle options)1414 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, 1415 Bundle options) { 1416 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1417 String[] receiverPermissions = receiverPermission == null ? null 1418 : new String[] {receiverPermission}; 1419 try { 1420 intent.prepareToLeaveProcess(this); 1421 ActivityManager.getService().broadcastIntentWithFeature( 1422 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1423 null, Activity.RESULT_OK, null, null, receiverPermissions, 1424 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, options, false, false, 1425 user.getIdentifier()); 1426 } catch (RemoteException e) { 1427 throw e.rethrowFromSystemServer(); 1428 } 1429 } 1430 1431 @Override sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)1432 public void sendBroadcastAsUser(Intent intent, UserHandle user, 1433 String receiverPermission, int appOp) { 1434 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1435 String[] receiverPermissions = receiverPermission == null ? null 1436 : new String[] {receiverPermission}; 1437 try { 1438 intent.prepareToLeaveProcess(this); 1439 ActivityManager.getService().broadcastIntentWithFeature( 1440 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1441 null, Activity.RESULT_OK, null, null, receiverPermissions, 1442 null /*excludedPermissions=*/, appOp, null, false, false, user.getIdentifier()); 1443 } catch (RemoteException e) { 1444 throw e.rethrowFromSystemServer(); 1445 } 1446 } 1447 1448 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1449 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 1450 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, 1451 int initialCode, String initialData, Bundle initialExtras) { 1452 sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE, 1453 null, resultReceiver, scheduler, initialCode, initialData, initialExtras); 1454 } 1455 1456 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1457 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 1458 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 1459 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 1460 sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, 1461 null, resultReceiver, scheduler, initialCode, initialData, initialExtras); 1462 } 1463 1464 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1465 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 1466 String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, 1467 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 1468 IIntentReceiver rd = null; 1469 if (resultReceiver != null) { 1470 if (mPackageInfo != null) { 1471 if (scheduler == null) { 1472 scheduler = mMainThread.getHandler(); 1473 } 1474 rd = mPackageInfo.getReceiverDispatcher( 1475 resultReceiver, getOuterContext(), scheduler, 1476 mMainThread.getInstrumentation(), false); 1477 } else { 1478 if (scheduler == null) { 1479 scheduler = mMainThread.getHandler(); 1480 } 1481 rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(), 1482 scheduler, null, false).getIIntentReceiver(); 1483 } 1484 } 1485 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1486 String[] receiverPermissions = receiverPermission == null ? null 1487 : new String[] {receiverPermission}; 1488 try { 1489 intent.prepareToLeaveProcess(this); 1490 ActivityManager.getService().broadcastIntentWithFeature( 1491 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1492 rd, initialCode, initialData, initialExtras, receiverPermissions, 1493 null /*excludedPermissions=*/, appOp, options, true, false, 1494 user.getIdentifier()); 1495 } catch (RemoteException e) { 1496 throw e.rethrowFromSystemServer(); 1497 } 1498 } 1499 1500 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, @Nullable Bundle initialExtras)1501 public void sendOrderedBroadcast(Intent intent, String receiverPermission, 1502 String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, 1503 int initialCode, String initialData, @Nullable Bundle initialExtras) { 1504 int intAppOp = AppOpsManager.OP_NONE; 1505 if (!TextUtils.isEmpty(receiverAppOp)) { 1506 intAppOp = AppOpsManager.strOpToOp(receiverAppOp); 1507 } 1508 sendOrderedBroadcastAsUser(intent, getUser(), 1509 receiverPermission, intAppOp, resultReceiver, scheduler, initialCode, initialData, 1510 initialExtras); 1511 } 1512 1513 @Override sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, String initialData, @Nullable Bundle initialExtras, Bundle options)1514 public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission, 1515 String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler, 1516 String initialData, @Nullable Bundle initialExtras, Bundle options) { 1517 int intAppOp = AppOpsManager.OP_NONE; 1518 if (!TextUtils.isEmpty(receiverAppOp)) { 1519 intAppOp = AppOpsManager.strOpToOp(receiverAppOp); 1520 } 1521 sendOrderedBroadcastAsUser(intent, getUser(), receiverPermission, intAppOp, options, 1522 resultReceiver, scheduler, initialCode, initialData, initialExtras); 1523 } 1524 1525 @Override 1526 @Deprecated sendStickyBroadcast(Intent intent)1527 public void sendStickyBroadcast(Intent intent) { 1528 warnIfCallingFromSystemProcess(); 1529 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1530 try { 1531 intent.prepareToLeaveProcess(this); 1532 ActivityManager.getService().broadcastIntentWithFeature( 1533 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1534 null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, 1535 AppOpsManager.OP_NONE, null, false, true, getUserId()); 1536 } catch (RemoteException e) { 1537 throw e.rethrowFromSystemServer(); 1538 } 1539 } 1540 1541 /** 1542 * <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the 1543 * Intent you are sending stays around after the broadcast is complete, 1544 * so that others can quickly retrieve that data through the return 1545 * value of {@link #registerReceiver(BroadcastReceiver, IntentFilter)}. In 1546 * all other ways, this behaves the same as 1547 * {@link #sendBroadcast(Intent)}. 1548 * 1549 * @deprecated Sticky broadcasts should not be used. They provide no security (anyone 1550 * can access them), no protection (anyone can modify them), and many other problems. 1551 * The recommended pattern is to use a non-sticky broadcast to report that <em>something</em> 1552 * has changed, with another mechanism for apps to retrieve the current value whenever 1553 * desired. 1554 * 1555 * @param intent The Intent to broadcast; all receivers matching this 1556 * Intent will receive the broadcast, and the Intent will be held to 1557 * be re-broadcast to future receivers. 1558 * @param options (optional) Additional sending options, generated from a 1559 * {@link android.app.BroadcastOptions}. 1560 * 1561 * @see #sendBroadcast(Intent) 1562 * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle) 1563 */ 1564 @Override 1565 @Deprecated sendStickyBroadcast(@onNull Intent intent, @Nullable Bundle options)1566 public void sendStickyBroadcast(@NonNull Intent intent, @Nullable Bundle options) { 1567 warnIfCallingFromSystemProcess(); 1568 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1569 try { 1570 intent.prepareToLeaveProcess(this); 1571 ActivityManager.getService().broadcastIntentWithFeature( 1572 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1573 null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, 1574 AppOpsManager.OP_NONE, options, false, true, getUserId()); 1575 } catch (RemoteException e) { 1576 throw e.rethrowFromSystemServer(); 1577 } 1578 } 1579 1580 @Override 1581 @Deprecated sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1582 public void sendStickyOrderedBroadcast(Intent intent, 1583 BroadcastReceiver resultReceiver, 1584 Handler scheduler, int initialCode, String initialData, 1585 Bundle initialExtras) { 1586 warnIfCallingFromSystemProcess(); 1587 IIntentReceiver rd = null; 1588 if (resultReceiver != null) { 1589 if (mPackageInfo != null) { 1590 if (scheduler == null) { 1591 scheduler = mMainThread.getHandler(); 1592 } 1593 rd = mPackageInfo.getReceiverDispatcher( 1594 resultReceiver, getOuterContext(), scheduler, 1595 mMainThread.getInstrumentation(), false); 1596 } else { 1597 if (scheduler == null) { 1598 scheduler = mMainThread.getHandler(); 1599 } 1600 rd = new LoadedApk.ReceiverDispatcher( 1601 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 1602 } 1603 } 1604 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1605 try { 1606 intent.prepareToLeaveProcess(this); 1607 ActivityManager.getService().broadcastIntentWithFeature( 1608 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1609 rd, initialCode, initialData, initialExtras, null, 1610 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true, 1611 getUserId()); 1612 } catch (RemoteException e) { 1613 throw e.rethrowFromSystemServer(); 1614 } 1615 } 1616 1617 @Override 1618 @Deprecated removeStickyBroadcast(Intent intent)1619 public void removeStickyBroadcast(Intent intent) { 1620 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1621 if (resolvedType != null) { 1622 intent = new Intent(intent); 1623 intent.setDataAndType(intent.getData(), resolvedType); 1624 } 1625 try { 1626 intent.prepareToLeaveProcess(this); 1627 ActivityManager.getService().unbroadcastIntent( 1628 mMainThread.getApplicationThread(), intent, getUserId()); 1629 } catch (RemoteException e) { 1630 throw e.rethrowFromSystemServer(); 1631 } 1632 } 1633 1634 @Override 1635 @Deprecated sendStickyBroadcastAsUser(Intent intent, UserHandle user)1636 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 1637 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1638 try { 1639 intent.prepareToLeaveProcess(this); 1640 ActivityManager.getService().broadcastIntentWithFeature( 1641 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1642 null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, 1643 AppOpsManager.OP_NONE, null, false, true, user.getIdentifier()); 1644 } catch (RemoteException e) { 1645 throw e.rethrowFromSystemServer(); 1646 } 1647 } 1648 1649 @Override 1650 @Deprecated sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options)1651 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) { 1652 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1653 try { 1654 intent.prepareToLeaveProcess(this); 1655 ActivityManager.getService().broadcastIntentWithFeature( 1656 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1657 null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/, 1658 AppOpsManager.OP_NONE, options, false, true, user.getIdentifier()); 1659 } catch (RemoteException e) { 1660 throw e.rethrowFromSystemServer(); 1661 } 1662 } 1663 1664 @Override 1665 @Deprecated sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)1666 public void sendStickyOrderedBroadcastAsUser(Intent intent, 1667 UserHandle user, BroadcastReceiver resultReceiver, 1668 Handler scheduler, int initialCode, String initialData, 1669 Bundle initialExtras) { 1670 IIntentReceiver rd = null; 1671 if (resultReceiver != null) { 1672 if (mPackageInfo != null) { 1673 if (scheduler == null) { 1674 scheduler = mMainThread.getHandler(); 1675 } 1676 rd = mPackageInfo.getReceiverDispatcher( 1677 resultReceiver, getOuterContext(), scheduler, 1678 mMainThread.getInstrumentation(), false); 1679 } else { 1680 if (scheduler == null) { 1681 scheduler = mMainThread.getHandler(); 1682 } 1683 rd = new LoadedApk.ReceiverDispatcher( 1684 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 1685 } 1686 } 1687 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1688 try { 1689 intent.prepareToLeaveProcess(this); 1690 ActivityManager.getService().broadcastIntentWithFeature( 1691 mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType, 1692 rd, initialCode, initialData, initialExtras, null, 1693 null /*excludedPermissions=*/, AppOpsManager.OP_NONE, null, true, true, 1694 user.getIdentifier()); 1695 } catch (RemoteException e) { 1696 throw e.rethrowFromSystemServer(); 1697 } 1698 } 1699 1700 @Override 1701 @Deprecated removeStickyBroadcastAsUser(Intent intent, UserHandle user)1702 public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { 1703 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 1704 if (resolvedType != null) { 1705 intent = new Intent(intent); 1706 intent.setDataAndType(intent.getData(), resolvedType); 1707 } 1708 try { 1709 intent.prepareToLeaveProcess(this); 1710 ActivityManager.getService().unbroadcastIntent( 1711 mMainThread.getApplicationThread(), intent, user.getIdentifier()); 1712 } catch (RemoteException e) { 1713 throw e.rethrowFromSystemServer(); 1714 } 1715 } 1716 1717 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)1718 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 1719 return registerReceiver(receiver, filter, null, null); 1720 } 1721 1722 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags)1723 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 1724 int flags) { 1725 return registerReceiver(receiver, filter, null, null, flags); 1726 } 1727 1728 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)1729 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 1730 String broadcastPermission, Handler scheduler) { 1731 return registerReceiverInternal(receiver, getUserId(), 1732 filter, broadcastPermission, scheduler, getOuterContext(), 0); 1733 } 1734 1735 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags)1736 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 1737 String broadcastPermission, Handler scheduler, int flags) { 1738 return registerReceiverInternal(receiver, getUserId(), 1739 filter, broadcastPermission, scheduler, getOuterContext(), flags); 1740 } 1741 1742 @Override registerReceiverForAllUsers(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)1743 public Intent registerReceiverForAllUsers(BroadcastReceiver receiver, 1744 IntentFilter filter, String broadcastPermission, Handler scheduler) { 1745 return registerReceiverAsUser(receiver, UserHandle.ALL, 1746 filter, broadcastPermission, scheduler); 1747 } 1748 1749 @Override registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)1750 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 1751 IntentFilter filter, String broadcastPermission, Handler scheduler) { 1752 return registerReceiverInternal(receiver, user.getIdentifier(), 1753 filter, broadcastPermission, scheduler, getOuterContext(), 0); 1754 } 1755 registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context, int flags)1756 private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, 1757 IntentFilter filter, String broadcastPermission, 1758 Handler scheduler, Context context, int flags) { 1759 IIntentReceiver rd = null; 1760 if (receiver != null) { 1761 if (mPackageInfo != null && context != null) { 1762 if (scheduler == null) { 1763 scheduler = mMainThread.getHandler(); 1764 } 1765 rd = mPackageInfo.getReceiverDispatcher( 1766 receiver, context, scheduler, 1767 mMainThread.getInstrumentation(), true); 1768 } else { 1769 if (scheduler == null) { 1770 scheduler = mMainThread.getHandler(); 1771 } 1772 rd = new LoadedApk.ReceiverDispatcher( 1773 receiver, context, scheduler, null, true).getIIntentReceiver(); 1774 } 1775 } 1776 try { 1777 final Intent intent = ActivityManager.getService().registerReceiverWithFeature( 1778 mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), 1779 AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId, 1780 flags); 1781 if (intent != null) { 1782 intent.setExtrasClassLoader(getClassLoader()); 1783 // TODO: determine at registration time if caller is 1784 // protecting themselves with signature permission 1785 intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent), 1786 getAttributionSource()); 1787 } 1788 return intent; 1789 } catch (RemoteException e) { 1790 throw e.rethrowFromSystemServer(); 1791 } 1792 } 1793 1794 @Override unregisterReceiver(BroadcastReceiver receiver)1795 public void unregisterReceiver(BroadcastReceiver receiver) { 1796 if (mPackageInfo != null) { 1797 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( 1798 getOuterContext(), receiver); 1799 try { 1800 ActivityManager.getService().unregisterReceiver(rd); 1801 } catch (RemoteException e) { 1802 throw e.rethrowFromSystemServer(); 1803 } 1804 } else { 1805 throw new RuntimeException("Not supported in system context"); 1806 } 1807 } 1808 validateServiceIntent(Intent service)1809 private void validateServiceIntent(Intent service) { 1810 if (service.getComponent() == null && service.getPackage() == null) { 1811 if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) { 1812 IllegalArgumentException ex = new IllegalArgumentException( 1813 "Service Intent must be explicit: " + service); 1814 throw ex; 1815 } else { 1816 Log.w(TAG, "Implicit intents with startService are not safe: " + service 1817 + " " + Debug.getCallers(2, 3)); 1818 } 1819 } 1820 } 1821 1822 @Override startService(Intent service)1823 public ComponentName startService(Intent service) { 1824 warnIfCallingFromSystemProcess(); 1825 return startServiceCommon(service, false, mUser); 1826 } 1827 1828 @Override startForegroundService(Intent service)1829 public ComponentName startForegroundService(Intent service) { 1830 warnIfCallingFromSystemProcess(); 1831 return startServiceCommon(service, true, mUser); 1832 } 1833 1834 @Override stopService(Intent service)1835 public boolean stopService(Intent service) { 1836 warnIfCallingFromSystemProcess(); 1837 return stopServiceCommon(service, mUser); 1838 } 1839 1840 @Override startServiceAsUser(Intent service, UserHandle user)1841 public ComponentName startServiceAsUser(Intent service, UserHandle user) { 1842 return startServiceCommon(service, false, user); 1843 } 1844 1845 @Override startForegroundServiceAsUser(Intent service, UserHandle user)1846 public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) { 1847 return startServiceCommon(service, true, user); 1848 } 1849 startServiceCommon(Intent service, boolean requireForeground, UserHandle user)1850 private ComponentName startServiceCommon(Intent service, boolean requireForeground, 1851 UserHandle user) { 1852 try { 1853 validateServiceIntent(service); 1854 service.prepareToLeaveProcess(this); 1855 ComponentName cn = ActivityManager.getService().startService( 1856 mMainThread.getApplicationThread(), service, 1857 service.resolveTypeIfNeeded(getContentResolver()), requireForeground, 1858 getOpPackageName(), getAttributionTag(), user.getIdentifier()); 1859 if (cn != null) { 1860 if (cn.getPackageName().equals("!")) { 1861 throw new SecurityException( 1862 "Not allowed to start service " + service 1863 + " without permission " + cn.getClassName()); 1864 } else if (cn.getPackageName().equals("!!")) { 1865 throw new SecurityException( 1866 "Unable to start service " + service 1867 + ": " + cn.getClassName()); 1868 } else if (cn.getPackageName().equals("?")) { 1869 throw ServiceStartNotAllowedException.newInstance(requireForeground, 1870 "Not allowed to start service " + service + ": " + cn.getClassName()); 1871 } 1872 } 1873 // If we started a foreground service in the same package, remember the stack trace. 1874 if (cn != null && requireForeground) { 1875 if (cn.getPackageName().equals(getOpPackageName())) { 1876 Service.setStartForegroundServiceStackTrace(cn.getClassName(), 1877 new StackTrace("Last startServiceCommon() call for this service was " 1878 + "made here")); 1879 } 1880 } 1881 return cn; 1882 } catch (RemoteException e) { 1883 throw e.rethrowFromSystemServer(); 1884 } 1885 } 1886 1887 @Override stopServiceAsUser(Intent service, UserHandle user)1888 public boolean stopServiceAsUser(Intent service, UserHandle user) { 1889 return stopServiceCommon(service, user); 1890 } 1891 stopServiceCommon(Intent service, UserHandle user)1892 private boolean stopServiceCommon(Intent service, UserHandle user) { 1893 try { 1894 validateServiceIntent(service); 1895 service.prepareToLeaveProcess(this); 1896 int res = ActivityManager.getService().stopService( 1897 mMainThread.getApplicationThread(), service, 1898 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier()); 1899 if (res < 0) { 1900 throw new SecurityException( 1901 "Not allowed to stop service " + service); 1902 } 1903 return res != 0; 1904 } catch (RemoteException e) { 1905 throw e.rethrowFromSystemServer(); 1906 } 1907 } 1908 1909 @Override bindService(Intent service, ServiceConnection conn, int flags)1910 public boolean bindService(Intent service, ServiceConnection conn, int flags) { 1911 warnIfCallingFromSystemProcess(); 1912 return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, 1913 getUser()); 1914 } 1915 1916 @Override bindService( Intent service, int flags, Executor executor, ServiceConnection conn)1917 public boolean bindService( 1918 Intent service, int flags, Executor executor, ServiceConnection conn) { 1919 return bindServiceCommon(service, conn, flags, null, null, executor, getUser()); 1920 } 1921 1922 @Override bindIsolatedService(Intent service, int flags, String instanceName, Executor executor, ServiceConnection conn)1923 public boolean bindIsolatedService(Intent service, int flags, String instanceName, 1924 Executor executor, ServiceConnection conn) { 1925 warnIfCallingFromSystemProcess(); 1926 if (instanceName == null) { 1927 throw new NullPointerException("null instanceName"); 1928 } 1929 return bindServiceCommon(service, conn, flags, instanceName, null, executor, getUser()); 1930 } 1931 1932 @Override bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user)1933 public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, 1934 UserHandle user) { 1935 return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, user); 1936 } 1937 1938 /** @hide */ 1939 @Override bindServiceAsUser(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user)1940 public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, 1941 Handler handler, UserHandle user) { 1942 if (handler == null) { 1943 throw new IllegalArgumentException("handler must not be null."); 1944 } 1945 return bindServiceCommon(service, conn, flags, null, handler, null, user); 1946 } 1947 1948 /** @hide */ 1949 @Override getServiceDispatcher(ServiceConnection conn, Handler handler, int flags)1950 public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler, 1951 int flags) { 1952 return mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); 1953 } 1954 1955 /** @hide */ 1956 @Override getIApplicationThread()1957 public IApplicationThread getIApplicationThread() { 1958 return mMainThread.getApplicationThread(); 1959 } 1960 1961 /** @hide */ 1962 @Override getMainThreadHandler()1963 public Handler getMainThreadHandler() { 1964 return mMainThread.getHandler(); 1965 } 1966 bindServiceCommon(Intent service, ServiceConnection conn, int flags, String instanceName, Handler handler, Executor executor, UserHandle user)1967 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, 1968 String instanceName, Handler handler, Executor executor, UserHandle user) { 1969 // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser. 1970 IServiceConnection sd; 1971 if (conn == null) { 1972 throw new IllegalArgumentException("connection is null"); 1973 } 1974 if (handler != null && executor != null) { 1975 throw new IllegalArgumentException("Handler and Executor both supplied"); 1976 } 1977 if (mPackageInfo != null) { 1978 if (executor != null) { 1979 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags); 1980 } else { 1981 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); 1982 } 1983 } else { 1984 throw new RuntimeException("Not supported in system context"); 1985 } 1986 validateServiceIntent(service); 1987 try { 1988 IBinder token = getActivityToken(); 1989 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null 1990 && mPackageInfo.getApplicationInfo().targetSdkVersion 1991 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 1992 flags |= BIND_WAIVE_PRIORITY; 1993 } 1994 service.prepareToLeaveProcess(this); 1995 int res = ActivityManager.getService().bindIsolatedService( 1996 mMainThread.getApplicationThread(), getActivityToken(), service, 1997 service.resolveTypeIfNeeded(getContentResolver()), 1998 sd, flags, instanceName, getOpPackageName(), user.getIdentifier()); 1999 if (res < 0) { 2000 throw new SecurityException( 2001 "Not allowed to bind to service " + service); 2002 } 2003 return res != 0; 2004 } catch (RemoteException e) { 2005 throw e.rethrowFromSystemServer(); 2006 } 2007 } 2008 2009 @Override updateServiceGroup(@onNull ServiceConnection conn, int group, int importance)2010 public void updateServiceGroup(@NonNull ServiceConnection conn, int group, int importance) { 2011 if (conn == null) { 2012 throw new IllegalArgumentException("connection is null"); 2013 } 2014 if (mPackageInfo != null) { 2015 IServiceConnection sd = mPackageInfo.lookupServiceDispatcher(conn, getOuterContext()); 2016 if (sd == null) { 2017 throw new IllegalArgumentException("ServiceConnection not currently bound: " 2018 + conn); 2019 } 2020 try { 2021 ActivityManager.getService().updateServiceGroup(sd, group, importance); 2022 } catch (RemoteException e) { 2023 throw e.rethrowFromSystemServer(); 2024 } 2025 } else { 2026 throw new RuntimeException("Not supported in system context"); 2027 } 2028 } 2029 2030 @Override unbindService(ServiceConnection conn)2031 public void unbindService(ServiceConnection conn) { 2032 if (conn == null) { 2033 throw new IllegalArgumentException("connection is null"); 2034 } 2035 if (mPackageInfo != null) { 2036 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( 2037 getOuterContext(), conn); 2038 try { 2039 ActivityManager.getService().unbindService(sd); 2040 } catch (RemoteException e) { 2041 throw e.rethrowFromSystemServer(); 2042 } 2043 } else { 2044 throw new RuntimeException("Not supported in system context"); 2045 } 2046 } 2047 2048 @Override startInstrumentation(ComponentName className, String profileFile, Bundle arguments)2049 public boolean startInstrumentation(ComponentName className, 2050 String profileFile, Bundle arguments) { 2051 try { 2052 if (arguments != null) { 2053 arguments.setAllowFds(false); 2054 } 2055 return ActivityManager.getService().startInstrumentation( 2056 className, profileFile, 0, arguments, null, null, getUserId(), 2057 null /* ABI override */); 2058 } catch (RemoteException e) { 2059 throw e.rethrowFromSystemServer(); 2060 } 2061 } 2062 2063 @Override getSystemService(String name)2064 public Object getSystemService(String name) { 2065 if (vmIncorrectContextUseEnabled()) { 2066 // Check incorrect Context usage. 2067 if (WINDOW_SERVICE.equals(name) && !isUiContext()) { 2068 final String errorMessage = "Tried to access visual service " 2069 + SystemServiceRegistry.getSystemServiceClassName(name) 2070 + " from a non-visual Context:" + getOuterContext(); 2071 final String message = "WindowManager should be accessed from Activity or other " 2072 + "visual Context. Use an Activity or a Context created with " 2073 + "Context#createWindowContext(int, Bundle), which are adjusted to " 2074 + "the configuration and visual bounds of an area on screen."; 2075 final Exception exception = new IllegalAccessException(errorMessage); 2076 StrictMode.onIncorrectContextUsed(message, exception); 2077 Log.e(TAG, errorMessage + " " + message, exception); 2078 } 2079 } 2080 return SystemServiceRegistry.getSystemService(this, name); 2081 } 2082 2083 @Override getSystemServiceName(Class<?> serviceClass)2084 public String getSystemServiceName(Class<?> serviceClass) { 2085 return SystemServiceRegistry.getSystemServiceName(serviceClass); 2086 } 2087 2088 /** @hide */ 2089 @Override isUiContext()2090 public boolean isUiContext() { 2091 switch (mContextType) { 2092 case CONTEXT_TYPE_ACTIVITY: 2093 case CONTEXT_TYPE_WINDOW_CONTEXT: 2094 case CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI: 2095 return true; 2096 case CONTEXT_TYPE_DISPLAY_CONTEXT: 2097 case CONTEXT_TYPE_NON_UI: { 2098 return false; 2099 } 2100 default: 2101 return false; 2102 } 2103 } 2104 2105 /** @hide */ 2106 @Override isConfigurationContext()2107 public boolean isConfigurationContext() { 2108 return isUiContext() || mIsConfigurationBasedContext; 2109 } 2110 2111 /** 2112 * Temporary workaround to permit incorrect usages of Context by SystemUI. 2113 * TODO(b/147647877): Fix usages and remove. 2114 */ 2115 @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck") isSystemOrSystemUI(Context context)2116 private static boolean isSystemOrSystemUI(Context context) { 2117 return ActivityThread.isSystem() || context.checkPermission( 2118 "android.permission.STATUS_BAR_SERVICE", 2119 Binder.getCallingPid(), 2120 Binder.getCallingUid()) == PERMISSION_GRANTED; 2121 } 2122 2123 @Override checkPermission(String permission, int pid, int uid)2124 public int checkPermission(String permission, int pid, int uid) { 2125 if (permission == null) { 2126 throw new IllegalArgumentException("permission is null"); 2127 } 2128 if (mParams.isRenouncedPermission(permission) 2129 && pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) { 2130 Log.v(TAG, "Treating renounced permission " + permission + " as denied"); 2131 return PERMISSION_DENIED; 2132 } 2133 return PermissionManager.checkPermission(permission, pid, uid); 2134 } 2135 2136 /** @hide */ 2137 @Override checkPermission(String permission, int pid, int uid, IBinder callerToken)2138 public int checkPermission(String permission, int pid, int uid, IBinder callerToken) { 2139 if (permission == null) { 2140 throw new IllegalArgumentException("permission is null"); 2141 } 2142 if (mParams.isRenouncedPermission(permission) 2143 && pid == android.os.Process.myPid() && uid == android.os.Process.myUid()) { 2144 Log.v(TAG, "Treating renounced permission " + permission + " as denied"); 2145 return PERMISSION_DENIED; 2146 } 2147 return checkPermission(permission, pid, uid); 2148 } 2149 2150 @Override checkCallingPermission(String permission)2151 public int checkCallingPermission(String permission) { 2152 if (permission == null) { 2153 throw new IllegalArgumentException("permission is null"); 2154 } 2155 2156 int pid = Binder.getCallingPid(); 2157 if (pid != Process.myPid()) { 2158 return checkPermission(permission, pid, Binder.getCallingUid()); 2159 } 2160 return PackageManager.PERMISSION_DENIED; 2161 } 2162 2163 @Override checkCallingOrSelfPermission(String permission)2164 public int checkCallingOrSelfPermission(String permission) { 2165 if (permission == null) { 2166 throw new IllegalArgumentException("permission is null"); 2167 } 2168 2169 return checkPermission(permission, Binder.getCallingPid(), 2170 Binder.getCallingUid()); 2171 } 2172 2173 @Override checkSelfPermission(String permission)2174 public int checkSelfPermission(String permission) { 2175 if (permission == null) { 2176 throw new IllegalArgumentException("permission is null"); 2177 } 2178 if (mParams.isRenouncedPermission(permission)) { 2179 Log.v(TAG, "Treating renounced permission " + permission + " as denied"); 2180 return PERMISSION_DENIED; 2181 } 2182 2183 return checkPermission(permission, Process.myPid(), Process.myUid()); 2184 } 2185 enforce( String permission, int resultOfCheck, boolean selfToo, int uid, String message)2186 private void enforce( 2187 String permission, int resultOfCheck, 2188 boolean selfToo, int uid, String message) { 2189 if (resultOfCheck != PERMISSION_GRANTED) { 2190 throw new SecurityException( 2191 (message != null ? (message + ": ") : "") + 2192 (selfToo 2193 ? "Neither user " + uid + " nor current process has " 2194 : "uid " + uid + " does not have ") + 2195 permission + 2196 "."); 2197 } 2198 } 2199 2200 @Override enforcePermission( String permission, int pid, int uid, String message)2201 public void enforcePermission( 2202 String permission, int pid, int uid, String message) { 2203 enforce(permission, 2204 checkPermission(permission, pid, uid), 2205 false, 2206 uid, 2207 message); 2208 } 2209 2210 @Override enforceCallingPermission(String permission, String message)2211 public void enforceCallingPermission(String permission, String message) { 2212 enforce(permission, 2213 checkCallingPermission(permission), 2214 false, 2215 Binder.getCallingUid(), 2216 message); 2217 } 2218 2219 @Override enforceCallingOrSelfPermission( String permission, String message)2220 public void enforceCallingOrSelfPermission( 2221 String permission, String message) { 2222 enforce(permission, 2223 checkCallingOrSelfPermission(permission), 2224 true, 2225 Binder.getCallingUid(), 2226 message); 2227 } 2228 2229 @Override grantUriPermission(String toPackage, Uri uri, int modeFlags)2230 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { 2231 try { 2232 ActivityManager.getService().grantUriPermission( 2233 mMainThread.getApplicationThread(), toPackage, 2234 ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); 2235 } catch (RemoteException e) { 2236 throw e.rethrowFromSystemServer(); 2237 } 2238 } 2239 2240 @Override revokeUriPermission(Uri uri, int modeFlags)2241 public void revokeUriPermission(Uri uri, int modeFlags) { 2242 try { 2243 ActivityManager.getService().revokeUriPermission( 2244 mMainThread.getApplicationThread(), null, 2245 ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); 2246 } catch (RemoteException e) { 2247 throw e.rethrowFromSystemServer(); 2248 } 2249 } 2250 2251 @Override revokeUriPermission(String targetPackage, Uri uri, int modeFlags)2252 public void revokeUriPermission(String targetPackage, Uri uri, int modeFlags) { 2253 try { 2254 ActivityManager.getService().revokeUriPermission( 2255 mMainThread.getApplicationThread(), targetPackage, 2256 ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); 2257 } catch (RemoteException e) { 2258 throw e.rethrowFromSystemServer(); 2259 } 2260 } 2261 2262 @Override checkUriPermission(Uri uri, int pid, int uid, int modeFlags)2263 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 2264 try { 2265 return ActivityManager.getService().checkUriPermission( 2266 ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags, 2267 resolveUserId(uri), null); 2268 } catch (RemoteException e) { 2269 throw e.rethrowFromSystemServer(); 2270 } 2271 } 2272 2273 @NonNull 2274 @Override checkUriPermissions(@onNull List<Uri> uris, int pid, int uid, int modeFlags)2275 public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid, 2276 int modeFlags) { 2277 try { 2278 return ActivityManager.getService().checkUriPermissions(uris, pid, uid, modeFlags, 2279 null); 2280 } catch (RemoteException e) { 2281 throw e.rethrowFromSystemServer(); 2282 } 2283 } 2284 2285 /** @hide */ 2286 @Override checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken)2287 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) { 2288 try { 2289 return ActivityManager.getService().checkUriPermission( 2290 ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags, 2291 resolveUserId(uri), callerToken); 2292 } catch (RemoteException e) { 2293 throw e.rethrowFromSystemServer(); 2294 } 2295 } 2296 resolveUserId(Uri uri)2297 private int resolveUserId(Uri uri) { 2298 return ContentProvider.getUserIdFromUri(uri, getUserId()); 2299 } 2300 2301 @Override checkCallingUriPermission(Uri uri, int modeFlags)2302 public int checkCallingUriPermission(Uri uri, int modeFlags) { 2303 int pid = Binder.getCallingPid(); 2304 if (pid != Process.myPid()) { 2305 return checkUriPermission(uri, pid, 2306 Binder.getCallingUid(), modeFlags); 2307 } 2308 return PackageManager.PERMISSION_DENIED; 2309 } 2310 2311 @NonNull 2312 @Override checkCallingUriPermissions(@onNull List<Uri> uris, int modeFlags)2313 public int[] checkCallingUriPermissions(@NonNull List<Uri> uris, int modeFlags) { 2314 int pid = Binder.getCallingPid(); 2315 if (pid != Process.myPid()) { 2316 return checkUriPermissions(uris, pid, Binder.getCallingUid(), modeFlags); 2317 } 2318 int[] res = new int[uris.size()]; 2319 Arrays.fill(res, PERMISSION_DENIED); 2320 return res; 2321 } 2322 2323 @Override checkCallingOrSelfUriPermission(Uri uri, int modeFlags)2324 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { 2325 return checkUriPermission(uri, Binder.getCallingPid(), 2326 Binder.getCallingUid(), modeFlags); 2327 } 2328 2329 @NonNull 2330 @Override checkCallingOrSelfUriPermissions(@onNull List<Uri> uris, int modeFlags)2331 public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris, int modeFlags) { 2332 return checkUriPermissions(uris, Binder.getCallingPid(), Binder.getCallingUid(), modeFlags); 2333 } 2334 2335 @Override checkUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags)2336 public int checkUriPermission(Uri uri, String readPermission, 2337 String writePermission, int pid, int uid, int modeFlags) { 2338 if (DEBUG) { 2339 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission=" 2340 + readPermission + " writePermission=" + writePermission 2341 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags); 2342 } 2343 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 2344 if (readPermission == null 2345 || checkPermission(readPermission, pid, uid) 2346 == PERMISSION_GRANTED) { 2347 return PERMISSION_GRANTED; 2348 } 2349 } 2350 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 2351 if (writePermission == null 2352 || checkPermission(writePermission, pid, uid) 2353 == PERMISSION_GRANTED) { 2354 return PERMISSION_GRANTED; 2355 } 2356 } 2357 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags) 2358 : PackageManager.PERMISSION_DENIED; 2359 } 2360 uriModeFlagToString(int uriModeFlags)2361 private String uriModeFlagToString(int uriModeFlags) { 2362 StringBuilder builder = new StringBuilder(); 2363 if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 2364 builder.append("read and "); 2365 } 2366 if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 2367 builder.append("write and "); 2368 } 2369 if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) { 2370 builder.append("persistable and "); 2371 } 2372 if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 2373 builder.append("prefix and "); 2374 } 2375 2376 if (builder.length() > 5) { 2377 builder.setLength(builder.length() - 5); 2378 return builder.toString(); 2379 } else { 2380 throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags); 2381 } 2382 } 2383 enforceForUri( int modeFlags, int resultOfCheck, boolean selfToo, int uid, Uri uri, String message)2384 private void enforceForUri( 2385 int modeFlags, int resultOfCheck, boolean selfToo, 2386 int uid, Uri uri, String message) { 2387 if (resultOfCheck != PERMISSION_GRANTED) { 2388 throw new SecurityException( 2389 (message != null ? (message + ": ") : "") + 2390 (selfToo 2391 ? "Neither user " + uid + " nor current process has " 2392 : "User " + uid + " does not have ") + 2393 uriModeFlagToString(modeFlags) + 2394 " permission on " + 2395 uri + 2396 "."); 2397 } 2398 } 2399 2400 @Override enforceUriPermission( Uri uri, int pid, int uid, int modeFlags, String message)2401 public void enforceUriPermission( 2402 Uri uri, int pid, int uid, int modeFlags, String message) { 2403 enforceForUri( 2404 modeFlags, checkUriPermission(uri, pid, uid, modeFlags), 2405 false, uid, uri, message); 2406 } 2407 2408 @Override enforceCallingUriPermission( Uri uri, int modeFlags, String message)2409 public void enforceCallingUriPermission( 2410 Uri uri, int modeFlags, String message) { 2411 enforceForUri( 2412 modeFlags, checkCallingUriPermission(uri, modeFlags), 2413 false, 2414 Binder.getCallingUid(), uri, message); 2415 } 2416 2417 @Override enforceCallingOrSelfUriPermission( Uri uri, int modeFlags, String message)2418 public void enforceCallingOrSelfUriPermission( 2419 Uri uri, int modeFlags, String message) { 2420 enforceForUri( 2421 modeFlags, 2422 checkCallingOrSelfUriPermission(uri, modeFlags), true, 2423 Binder.getCallingUid(), uri, message); 2424 } 2425 2426 @Override enforceUriPermission( Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags, String message)2427 public void enforceUriPermission( 2428 Uri uri, String readPermission, String writePermission, 2429 int pid, int uid, int modeFlags, String message) { 2430 enforceForUri(modeFlags, 2431 checkUriPermission( 2432 uri, readPermission, writePermission, pid, uid, 2433 modeFlags), 2434 false, 2435 uid, 2436 uri, 2437 message); 2438 } 2439 2440 /** 2441 * Logs a warning if the system process directly called a method such as 2442 * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}. 2443 * The "AsUser" variants allow us to properly enforce the user's restrictions. 2444 */ warnIfCallingFromSystemProcess()2445 private void warnIfCallingFromSystemProcess() { 2446 if (Process.myUid() == Process.SYSTEM_UID) { 2447 Slog.w(TAG, "Calling a method in the system process without a qualified user: " 2448 + Debug.getCallers(5)); 2449 } 2450 } 2451 createResources(IBinder activityToken, LoadedApk pi, String splitName, @Nullable Integer overrideDisplayId, Configuration overrideConfig, CompatibilityInfo compatInfo, List<ResourcesLoader> resourcesLoader)2452 private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName, 2453 @Nullable Integer overrideDisplayId, Configuration overrideConfig, 2454 CompatibilityInfo compatInfo, List<ResourcesLoader> resourcesLoader) { 2455 final String[] splitResDirs; 2456 final ClassLoader classLoader; 2457 try { 2458 splitResDirs = pi.getSplitPaths(splitName); 2459 classLoader = pi.getSplitClassLoader(splitName); 2460 } catch (NameNotFoundException e) { 2461 throw new RuntimeException(e); 2462 } 2463 return ResourcesManager.getInstance().getResources(activityToken, 2464 pi.getResDir(), 2465 splitResDirs, 2466 pi.getOverlayDirs(), 2467 pi.getOverlayPaths(), 2468 pi.getApplicationInfo().sharedLibraryFiles, 2469 overrideDisplayId, 2470 overrideConfig, 2471 compatInfo, 2472 classLoader, 2473 resourcesLoader); 2474 } 2475 2476 @Override createApplicationContext(ApplicationInfo application, int flags)2477 public Context createApplicationContext(ApplicationInfo application, int flags) 2478 throws NameNotFoundException { 2479 LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(), 2480 flags | CONTEXT_REGISTER_PACKAGE); 2481 if (pi != null) { 2482 ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY, 2483 mAttributionSource.getAttributionTag(), 2484 mAttributionSource.getNext(), 2485 null, mToken, new UserHandle(UserHandle.getUserId(application.uid)), 2486 flags, null, null); 2487 2488 final int displayId = getDisplayId(); 2489 final Integer overrideDisplayId = mForceDisplayOverrideInResources 2490 ? displayId : null; 2491 2492 c.setResources(createResources(mToken, pi, null, overrideDisplayId, null, 2493 getDisplayAdjustments(displayId).getCompatibilityInfo(), null)); 2494 if (c.mResources != null) { 2495 return c; 2496 } 2497 } 2498 2499 throw new PackageManager.NameNotFoundException( 2500 "Application package " + application.packageName + " not found"); 2501 } 2502 2503 @Override createPackageContext(String packageName, int flags)2504 public Context createPackageContext(String packageName, int flags) 2505 throws NameNotFoundException { 2506 return createPackageContextAsUser(packageName, flags, mUser); 2507 } 2508 2509 @Override createPackageContextAsUser(String packageName, int flags, UserHandle user)2510 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 2511 throws NameNotFoundException { 2512 if (packageName.equals("system") || packageName.equals("android")) { 2513 // The system resources are loaded in every application, so we can safely copy 2514 // the context without reloading Resources. 2515 return new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2516 mAttributionSource.getAttributionTag(), 2517 mAttributionSource.getNext(), 2518 null, mToken, user, flags, null, null); 2519 } 2520 2521 LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), 2522 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier()); 2523 if (pi != null) { 2524 ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams, 2525 mAttributionSource.getAttributionTag(), 2526 mAttributionSource.getNext(), 2527 null, mToken, user, flags, null, null); 2528 2529 final int displayId = getDisplayId(); 2530 final Integer overrideDisplayId = mForceDisplayOverrideInResources 2531 ? displayId : null; 2532 2533 c.setResources(createResources(mToken, pi, null, overrideDisplayId, null, 2534 getDisplayAdjustments(displayId).getCompatibilityInfo(), null)); 2535 if (c.mResources != null) { 2536 return c; 2537 } 2538 } 2539 2540 // Should be a better exception. 2541 throw new PackageManager.NameNotFoundException( 2542 "Application package " + packageName + " not found"); 2543 } 2544 2545 @Override createContextAsUser(UserHandle user, @CreatePackageOptions int flags)2546 public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) { 2547 try { 2548 return createPackageContextAsUser(getPackageName(), flags, user); 2549 } catch (NameNotFoundException e) { 2550 throw new IllegalStateException("Own package not found: package=" + getPackageName()); 2551 } 2552 } 2553 2554 @Override createContextForSplit(String splitName)2555 public Context createContextForSplit(String splitName) throws NameNotFoundException { 2556 if (!mPackageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) { 2557 // All Splits are always loaded. 2558 return this; 2559 } 2560 2561 final ClassLoader classLoader = mPackageInfo.getSplitClassLoader(splitName); 2562 final String[] paths = mPackageInfo.getSplitPaths(splitName); 2563 2564 final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2565 mAttributionSource.getAttributionTag(), 2566 mAttributionSource.getNext(), 2567 splitName, mToken, mUser, mFlags, classLoader, null); 2568 2569 context.setResources(ResourcesManager.getInstance().getResources( 2570 mToken, 2571 mPackageInfo.getResDir(), 2572 paths, 2573 mPackageInfo.getOverlayDirs(), 2574 mPackageInfo.getOverlayPaths(), 2575 mPackageInfo.getApplicationInfo().sharedLibraryFiles, 2576 mForceDisplayOverrideInResources ? getDisplayId() : null, 2577 null, 2578 mPackageInfo.getCompatibilityInfo(), 2579 classLoader, 2580 mResources.getLoaders())); 2581 return context; 2582 } 2583 2584 @Override createConfigurationContext(Configuration overrideConfiguration)2585 public Context createConfigurationContext(Configuration overrideConfiguration) { 2586 if (overrideConfiguration == null) { 2587 throw new IllegalArgumentException("overrideConfiguration must not be null"); 2588 } 2589 2590 if (mForceDisplayOverrideInResources) { 2591 // Ensure the resources display metrics are adjusted to match the display this context 2592 // is based on. 2593 Configuration displayAdjustedConfig = new Configuration(); 2594 displayAdjustedConfig.setTo(mDisplay.getDisplayAdjustments().getConfiguration(), 2595 ActivityInfo.CONFIG_WINDOW_CONFIGURATION, 1); 2596 displayAdjustedConfig.updateFrom(overrideConfiguration); 2597 overrideConfiguration = displayAdjustedConfig; 2598 } 2599 2600 ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2601 mAttributionSource.getAttributionTag(), 2602 mAttributionSource.getNext(), 2603 mSplitName, mToken, mUser, mFlags, mClassLoader, null); 2604 context.mIsConfigurationBasedContext = true; 2605 2606 final int displayId = getDisplayId(); 2607 final Integer overrideDisplayId = mForceDisplayOverrideInResources 2608 ? displayId : null; 2609 context.setResources(createResources(mToken, mPackageInfo, mSplitName, overrideDisplayId, 2610 overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(), 2611 mResources.getLoaders())); 2612 return context; 2613 } 2614 2615 @Override createDisplayContext(Display display)2616 public Context createDisplayContext(Display display) { 2617 if (display == null) { 2618 throw new IllegalArgumentException("display must not be null"); 2619 } 2620 2621 ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2622 mAttributionSource.getAttributionTag(), 2623 mAttributionSource.getNext(), 2624 mSplitName, mToken, mUser, mFlags, mClassLoader, null); 2625 2626 final int displayId = display.getDisplayId(); 2627 2628 // Ensure the resources display metrics are adjusted to match the provided display. 2629 Configuration overrideConfig = new Configuration(); 2630 overrideConfig.setTo(display.getDisplayAdjustments().getConfiguration(), 2631 ActivityInfo.CONFIG_WINDOW_CONFIGURATION, 1); 2632 2633 context.setResources(createResources(mToken, mPackageInfo, mSplitName, displayId, 2634 overrideConfig, display.getDisplayAdjustments().getCompatibilityInfo(), 2635 mResources.getLoaders())); 2636 context.mDisplay = display; 2637 // Inherit context type if the container is from System or System UI context to bypass 2638 // UI context check. 2639 context.mContextType = mContextType == CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI 2640 ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI : CONTEXT_TYPE_DISPLAY_CONTEXT; 2641 // Display contexts and any context derived from a display context should always override 2642 // the display that would otherwise be inherited from mToken (or the global configuration if 2643 // mToken is null). 2644 context.mForceDisplayOverrideInResources = true; 2645 // The configuration is overridden by display adjustments' configuration and won't receive 2646 // configuration changes. This context won't be regarded as having the proper configuration 2647 // anymore. 2648 context.mIsConfigurationBasedContext = false; 2649 return context; 2650 } 2651 2652 @NonNull 2653 @Override createWindowContext(@indowType int type, @Nullable Bundle options)2654 public WindowContext createWindowContext(@WindowType int type, 2655 @Nullable Bundle options) { 2656 if (getDisplay() == null) { 2657 throw new UnsupportedOperationException("Please call this API with context associated" 2658 + " with a display instance, such as Activity or context created via" 2659 + " Context#createDisplayContext(Display), or try to invoke" 2660 + " Context#createWindowContext(Display, int, Bundle)"); 2661 } 2662 return createWindowContextInternal(getDisplay(), type, options); 2663 } 2664 2665 @NonNull 2666 @Override createWindowContext(@onNull Display display, @WindowType int type, @Nullable Bundle options)2667 public WindowContext createWindowContext(@NonNull Display display, @WindowType int type, 2668 @Nullable Bundle options) { 2669 if (display == null) { 2670 throw new IllegalArgumentException("Display must not be null"); 2671 } 2672 return createWindowContextInternal(display, type, options); 2673 } 2674 2675 /** 2676 * The internal implementation of {@link Context#createWindowContext(int, Bundle)} and 2677 * {@link Context#createWindowContext(Display, int, Bundle)}. 2678 * 2679 * @param display The {@link Display} instance to be associated with. 2680 * 2681 * @see Context#createWindowContext(Display, int, Bundle) 2682 * @see Context#createWindowContext(int, Bundle) 2683 */ createWindowContextInternal(@onNull Display display, @WindowType int type, @Nullable Bundle options)2684 private WindowContext createWindowContextInternal(@NonNull Display display, 2685 @WindowType int type, @Nullable Bundle options) { 2686 // Step 1. Create a WindowTokenClient to associate with the WindowContext's Resources 2687 // instance and it will be later used to receive configuration updates from the 2688 // server side. 2689 final WindowTokenClient windowTokenClient = new WindowTokenClient(); 2690 2691 // Step 2. Create the base context of the window context, it will also create a Resources 2692 // associated with the WindowTokenClient and set the token to the base context. 2693 final ContextImpl windowContextBase = createWindowContextBase(windowTokenClient, 2694 display.getDisplayId()); 2695 2696 // Step 3. Create a WindowContext instance and set it as the outer context of the base 2697 // context to make the service obtained by #getSystemService(String) able to query 2698 // the WindowContext's WindowManager instead of the default one. 2699 final WindowContext windowContext = new WindowContext(windowContextBase, type, options); 2700 windowContextBase.setOuterContext(windowContext); 2701 2702 // Step 4. Attach the WindowContext to the WindowTokenClient. In this way, when there's a 2703 // configuration update from the server side, the update will then apply to 2704 // WindowContext's resources. 2705 windowTokenClient.attachContext(windowContext); 2706 2707 // Step 5. Associate the WindowContext's token to a DisplayArea. 2708 windowContext.attachToDisplayArea(); 2709 2710 return windowContext; 2711 } 2712 2713 @NonNull 2714 @Override createTokenContext(@onNull IBinder token, @NonNull Display display)2715 public Context createTokenContext(@NonNull IBinder token, @NonNull Display display) { 2716 if (display == null) { 2717 throw new IllegalArgumentException("Display must not be null"); 2718 } 2719 return createWindowContextBase(token, display.getDisplayId()); 2720 } 2721 2722 /** 2723 * Creates the base {@link Context} for UI context to associate with a non-{@link Activity} 2724 * window. 2725 * 2726 * @param token The token to associate with {@link Resources} 2727 * @param displayId The ID of {@link Display} to associate with. 2728 * 2729 * @see #createWindowContext(Display, int, Bundle) 2730 * @see #createTokenContext(IBinder, Display) 2731 */ 2732 @UiContext createWindowContextBase(@onNull IBinder token, int displayId)2733 ContextImpl createWindowContextBase(@NonNull IBinder token, int displayId) { 2734 ContextImpl baseContext = new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2735 mAttributionSource.getAttributionTag(), 2736 mAttributionSource.getNext(), 2737 mSplitName, token, mUser, mFlags, mClassLoader, null); 2738 // Window contexts receive configurations directly from the server and as such do not 2739 // need to override their display in ResourcesManager. 2740 baseContext.mForceDisplayOverrideInResources = false; 2741 baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT; 2742 2743 final Resources windowContextResources = createWindowContextResources(baseContext); 2744 baseContext.setResources(windowContextResources); 2745 // Associate the display with window context resources so that configuration update from 2746 // the server side will also apply to the display's metrics. 2747 baseContext.mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId, 2748 windowContextResources); 2749 2750 return baseContext; 2751 } 2752 2753 /** 2754 * Creates the {@link Resources} to associate with the {@link WindowContext}'s token. 2755 * 2756 * When there's a {@link Configuration} update, this Resources instance will be updated to match 2757 * the new configuration. 2758 * 2759 * @see WindowTokenClient 2760 * @see #getWindowContextToken() 2761 */ createWindowContextResources(@onNull ContextImpl windowContextBase)2762 private static Resources createWindowContextResources(@NonNull ContextImpl windowContextBase) { 2763 final LoadedApk packageInfo = windowContextBase.mPackageInfo; 2764 final ClassLoader classLoader = windowContextBase.getClassLoader(); 2765 final IBinder token = windowContextBase.getWindowContextToken(); 2766 2767 final String resDir = packageInfo.getResDir(); 2768 final String[] splitResDirs = packageInfo.getSplitResDirs(); 2769 final String[] legacyOverlayDirs = packageInfo.getOverlayDirs(); 2770 final String[] overlayPaths = packageInfo.getOverlayPaths(); 2771 final String[] libDirs = packageInfo.getApplicationInfo().sharedLibraryFiles; 2772 final int displayId = windowContextBase.getDisplayId(); 2773 final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY) 2774 ? packageInfo.getCompatibilityInfo() 2775 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; 2776 final List<ResourcesLoader> loaders = windowContextBase.mResources.getLoaders(); 2777 2778 return windowContextBase.mResourcesManager.createBaseTokenResources(token, resDir, 2779 splitResDirs, legacyOverlayDirs, overlayPaths, libDirs, displayId, 2780 null /* overrideConfig */, compatInfo, classLoader, loaders); 2781 } 2782 2783 @NonNull 2784 @Override createContext(@onNull ContextParams contextParams)2785 public Context createContext(@NonNull ContextParams contextParams) { 2786 return new ContextImpl(this, mMainThread, mPackageInfo, contextParams, 2787 contextParams.getAttributionTag(), contextParams.getNextAttributionSource(), 2788 mSplitName, mToken, mUser, mFlags, mClassLoader, null); 2789 } 2790 2791 @Override createAttributionContext(@ullable String attributionTag)2792 public @NonNull Context createAttributionContext(@Nullable String attributionTag) { 2793 return createContext( 2794 new ContextParams.Builder(mParams).setAttributionTag(attributionTag).build()); 2795 } 2796 2797 @Override createDeviceProtectedStorageContext()2798 public Context createDeviceProtectedStorageContext() { 2799 final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) 2800 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE; 2801 return new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2802 mAttributionSource.getAttributionTag(), 2803 mAttributionSource.getNext(), 2804 mSplitName, mToken, mUser, flags, mClassLoader, null); 2805 } 2806 2807 @Override createCredentialProtectedStorageContext()2808 public Context createCredentialProtectedStorageContext() { 2809 final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE) 2810 | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE; 2811 return new ContextImpl(this, mMainThread, mPackageInfo, mParams, 2812 mAttributionSource.getAttributionTag(), 2813 mAttributionSource.getNext(), 2814 mSplitName, mToken, mUser, flags, mClassLoader, null); 2815 } 2816 2817 @Override isRestricted()2818 public boolean isRestricted() { 2819 return (mFlags & Context.CONTEXT_RESTRICTED) != 0; 2820 } 2821 2822 @Override isDeviceProtectedStorage()2823 public boolean isDeviceProtectedStorage() { 2824 return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0; 2825 } 2826 2827 @Override isCredentialProtectedStorage()2828 public boolean isCredentialProtectedStorage() { 2829 return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0; 2830 } 2831 2832 @Override canLoadUnsafeResources()2833 public boolean canLoadUnsafeResources() { 2834 if (getPackageName().equals(getOpPackageName())) { 2835 return true; 2836 } 2837 return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0; 2838 } 2839 2840 @Override getDisplay()2841 public Display getDisplay() { 2842 if (!isAssociatedWithDisplay()) { 2843 throw new UnsupportedOperationException("Tried to obtain display from a Context not " 2844 + "associated with one. Only visual Contexts (such as Activity or one created " 2845 + "with Context#createWindowContext) or ones created with " 2846 + "Context#createDisplayContext are associated with displays. Other types of " 2847 + "Contexts are typically related to background entities and may return an " 2848 + "arbitrary display."); 2849 } 2850 return getDisplayNoVerify(); 2851 } 2852 isAssociatedWithDisplay()2853 private boolean isAssociatedWithDisplay() { 2854 switch (mContextType) { 2855 case CONTEXT_TYPE_DISPLAY_CONTEXT: 2856 case CONTEXT_TYPE_ACTIVITY: 2857 case CONTEXT_TYPE_WINDOW_CONTEXT: 2858 // TODO(b/170369943): Remove after WindowContext migration 2859 case CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI: 2860 return true; 2861 default: 2862 return false; 2863 } 2864 } 2865 2866 @Override getDisplayNoVerify()2867 public Display getDisplayNoVerify() { 2868 if (mDisplay == null) { 2869 return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY, 2870 mResources); 2871 } 2872 2873 return mDisplay; 2874 } 2875 2876 @Override getDisplayId()2877 public int getDisplayId() { 2878 final Display display = getDisplayNoVerify(); 2879 return display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY; 2880 } 2881 2882 @Override updateDisplay(int displayId)2883 public void updateDisplay(int displayId) { 2884 mDisplay = mResourcesManager.getAdjustedDisplay(displayId, mResources); 2885 if (mContextType == CONTEXT_TYPE_NON_UI) { 2886 mContextType = CONTEXT_TYPE_DISPLAY_CONTEXT; 2887 } 2888 } 2889 2890 @Override getDisplayAdjustments(int displayId)2891 public DisplayAdjustments getDisplayAdjustments(int displayId) { 2892 return mResources.getDisplayAdjustments(); 2893 } 2894 2895 @Override getDataDir()2896 public File getDataDir() { 2897 if (mPackageInfo != null) { 2898 File res = null; 2899 if (isCredentialProtectedStorage()) { 2900 res = mPackageInfo.getCredentialProtectedDataDirFile(); 2901 } else if (isDeviceProtectedStorage()) { 2902 res = mPackageInfo.getDeviceProtectedDataDirFile(); 2903 } else { 2904 res = mPackageInfo.getDataDirFile(); 2905 } 2906 2907 if (res != null) { 2908 if (!res.exists() && android.os.Process.myUid() == android.os.Process.SYSTEM_UID) { 2909 Log.wtf(TAG, "Data directory doesn't exist for package " + getPackageName(), 2910 new Throwable()); 2911 } 2912 return res; 2913 } else { 2914 throw new RuntimeException( 2915 "No data directory found for package " + getPackageName()); 2916 } 2917 } else { 2918 throw new RuntimeException( 2919 "No package details found for package " + getPackageName()); 2920 } 2921 } 2922 2923 @Override getDir(String name, int mode)2924 public File getDir(String name, int mode) { 2925 checkMode(mode); 2926 name = "app_" + name; 2927 File file = makeFilename(getDataDir(), name); 2928 if (!file.exists()) { 2929 file.mkdir(); 2930 setFilePermissionsFromMode(file.getPath(), mode, 2931 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH); 2932 } 2933 return file; 2934 } 2935 2936 /** {@hide} */ 2937 @Override getUser()2938 public UserHandle getUser() { 2939 return mUser; 2940 } 2941 2942 /** {@hide} */ 2943 @Override getUserId()2944 public int getUserId() { 2945 return mUser.getIdentifier(); 2946 } 2947 2948 /** @hide */ 2949 @Override getAutofillClient()2950 public AutofillClient getAutofillClient() { 2951 return mAutofillClient; 2952 } 2953 2954 /** @hide */ 2955 @Override setAutofillClient(AutofillClient client)2956 public void setAutofillClient(AutofillClient client) { 2957 mAutofillClient = client; 2958 } 2959 2960 /** @hide */ 2961 @Override getAutofillOptions()2962 public AutofillOptions getAutofillOptions() { 2963 return mAutofillOptions; 2964 } 2965 2966 /** @hide */ 2967 @Override setAutofillOptions(AutofillOptions options)2968 public void setAutofillOptions(AutofillOptions options) { 2969 mAutofillOptions = options; 2970 } 2971 2972 /** @hide */ 2973 @Override getContentCaptureOptions()2974 public ContentCaptureOptions getContentCaptureOptions() { 2975 return mContentCaptureOptions; 2976 } 2977 2978 /** @hide */ 2979 @Override setContentCaptureOptions(ContentCaptureOptions options)2980 public void setContentCaptureOptions(ContentCaptureOptions options) { 2981 mContentCaptureOptions = options; 2982 } 2983 2984 @Override finalize()2985 protected void finalize() throws Throwable { 2986 // If mToken is a WindowTokenClient, the Context is usually associated with a 2987 // WindowContainer. We should detach from WindowContainer when the Context is finalized 2988 // if this Context is not a WindowContext. WindowContext finalization is handled in 2989 // WindowContext class. 2990 if (mToken instanceof WindowTokenClient && mOwnsToken) { 2991 ((WindowTokenClient) mToken).detachFromWindowContainerIfNeeded(); 2992 } 2993 super.finalize(); 2994 } 2995 2996 @UnsupportedAppUsage createSystemContext(ActivityThread mainThread)2997 static ContextImpl createSystemContext(ActivityThread mainThread) { 2998 LoadedApk packageInfo = new LoadedApk(mainThread); 2999 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, 3000 ContextParams.EMPTY, null, null, null, null, null, 0, null, null); 3001 context.setResources(packageInfo.getResources()); 3002 context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), 3003 context.mResourcesManager.getDisplayMetrics()); 3004 context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI; 3005 return context; 3006 } 3007 3008 /** 3009 * System Context to be used for UI. This Context has resources that can be themed. 3010 * Make sure that the created system UI context shares the same LoadedApk as the system context. 3011 * @param systemContext The system context which created by 3012 * {@link #createSystemContext(ActivityThread)}. 3013 * @param displayId The ID of the display where the UI is shown. 3014 */ createSystemUiContext(ContextImpl systemContext, int displayId)3015 static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) { 3016 final WindowTokenClient token = new WindowTokenClient(); 3017 final ContextImpl context = systemContext.createWindowContextBase(token, displayId); 3018 token.attachContext(context); 3019 token.attachToDisplayContent(displayId); 3020 context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI; 3021 context.mOwnsToken = true; 3022 3023 return context; 3024 } 3025 3026 @UnsupportedAppUsage createAppContext(ActivityThread mainThread, LoadedApk packageInfo)3027 static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { 3028 return createAppContext(mainThread, packageInfo, null); 3029 } 3030 createAppContext(ActivityThread mainThread, LoadedApk packageInfo, String opPackageName)3031 static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo, 3032 String opPackageName) { 3033 if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); 3034 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, 3035 ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName); 3036 context.setResources(packageInfo.getResources()); 3037 context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI 3038 : CONTEXT_TYPE_NON_UI; 3039 return context; 3040 } 3041 3042 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) createActivityContext(ActivityThread mainThread, LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, Configuration overrideConfiguration)3043 static ContextImpl createActivityContext(ActivityThread mainThread, 3044 LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, 3045 Configuration overrideConfiguration) { 3046 if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); 3047 3048 String[] splitDirs = packageInfo.getSplitResDirs(); 3049 ClassLoader classLoader = packageInfo.getClassLoader(); 3050 3051 if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) { 3052 Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies"); 3053 try { 3054 classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName); 3055 splitDirs = packageInfo.getSplitPaths(activityInfo.splitName); 3056 } catch (NameNotFoundException e) { 3057 // Nothing above us can handle a NameNotFoundException, better crash. 3058 throw new RuntimeException(e); 3059 } finally { 3060 Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); 3061 } 3062 } 3063 3064 final String attributionTag; 3065 if (activityInfo.attributionTags != null && activityInfo.attributionTags.length > 0) { 3066 attributionTag = activityInfo.attributionTags[0]; 3067 } else { 3068 attributionTag = null; 3069 } 3070 3071 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY, 3072 attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader, 3073 null); 3074 context.mContextType = CONTEXT_TYPE_ACTIVITY; 3075 context.mIsConfigurationBasedContext = true; 3076 3077 // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY. 3078 displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY; 3079 3080 final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY) 3081 ? packageInfo.getCompatibilityInfo() 3082 : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; 3083 3084 final ResourcesManager resourcesManager = ResourcesManager.getInstance(); 3085 3086 // Create the base resources for which all configuration contexts for this Activity 3087 // will be rebased upon. 3088 context.setResources(resourcesManager.createBaseTokenResources(activityToken, 3089 packageInfo.getResDir(), 3090 splitDirs, 3091 packageInfo.getOverlayDirs(), 3092 packageInfo.getOverlayPaths(), 3093 packageInfo.getApplicationInfo().sharedLibraryFiles, 3094 displayId, 3095 overrideConfiguration, 3096 compatInfo, 3097 classLoader, 3098 packageInfo.getApplication() == null ? null 3099 : packageInfo.getApplication().getResources().getLoaders())); 3100 context.mDisplay = resourcesManager.getAdjustedDisplay(displayId, 3101 context.getResources()); 3102 return context; 3103 } 3104 ContextImpl(@ullable ContextImpl container, @NonNull ActivityThread mainThread, @NonNull LoadedApk packageInfo, @NonNull ContextParams params, @Nullable String attributionTag, @Nullable AttributionSource nextAttributionSource, @Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user, int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName)3105 private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread, 3106 @NonNull LoadedApk packageInfo, @NonNull ContextParams params, 3107 @Nullable String attributionTag, @Nullable AttributionSource nextAttributionSource, 3108 @Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user, 3109 int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) { 3110 mOuterContext = this; 3111 3112 // If creator didn't specify which storage to use, use the default 3113 // location for application. 3114 if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE 3115 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) { 3116 final File dataDir = packageInfo.getDataDirFile(); 3117 if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) { 3118 flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE; 3119 } else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) { 3120 flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE; 3121 } 3122 } 3123 3124 mMainThread = mainThread; 3125 mToken = token; 3126 mFlags = flags; 3127 3128 if (user == null) { 3129 user = Process.myUserHandle(); 3130 } 3131 mUser = user; 3132 3133 mPackageInfo = packageInfo; 3134 mSplitName = splitName; 3135 mClassLoader = classLoader; 3136 mResourcesManager = ResourcesManager.getInstance(); 3137 3138 String opPackageName; 3139 3140 if (container != null) { 3141 mBasePackageName = container.mBasePackageName; 3142 opPackageName = container.mOpPackageName; 3143 setResources(container.mResources); 3144 mDisplay = container.mDisplay; 3145 mForceDisplayOverrideInResources = container.mForceDisplayOverrideInResources; 3146 mIsConfigurationBasedContext = container.mIsConfigurationBasedContext; 3147 mContextType = container.mContextType; 3148 mContentCaptureOptions = container.mContentCaptureOptions; 3149 } else { 3150 mBasePackageName = packageInfo.mPackageName; 3151 ApplicationInfo ainfo = packageInfo.getApplicationInfo(); 3152 if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) { 3153 // Special case: system components allow themselves to be loaded in to other 3154 // processes. For purposes of app ops, we must then consider the context as 3155 // belonging to the package of this process, not the system itself, otherwise 3156 // the package+uid verifications in app ops will fail. 3157 opPackageName = ActivityThread.currentPackageName(); 3158 } else { 3159 opPackageName = mBasePackageName; 3160 } 3161 } 3162 3163 mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName; 3164 mParams = Objects.requireNonNull(params); 3165 mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource, 3166 params.getRenouncedPermissions()); 3167 mContentResolver = new ApplicationContentResolver(this, mainThread); 3168 } 3169 createAttributionSource(@ullable String attributionTag, @Nullable AttributionSource nextAttributionSource, @Nullable Set<String> renouncedPermissions)3170 private @NonNull AttributionSource createAttributionSource(@Nullable String attributionTag, 3171 @Nullable AttributionSource nextAttributionSource, 3172 @Nullable Set<String> renouncedPermissions) { 3173 AttributionSource attributionSource = new AttributionSource(Process.myUid(), 3174 mOpPackageName, attributionTag, renouncedPermissions, nextAttributionSource); 3175 // If we want to access protected data on behalf of another app we need to 3176 // tell the OS that we opt in to participate in the attribution chain. 3177 if (nextAttributionSource != null) { 3178 attributionSource = getSystemService(PermissionManager.class) 3179 .registerAttributionSource(attributionSource); 3180 } 3181 return attributionSource; 3182 } 3183 setResources(Resources r)3184 void setResources(Resources r) { 3185 if (r instanceof CompatResources) { 3186 ((CompatResources) r).setContext(this); 3187 } 3188 mResources = r; 3189 } 3190 installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader)3191 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 3192 mPackageInfo.installSystemApplicationInfo(info, classLoader); 3193 } 3194 3195 @UnsupportedAppUsage scheduleFinalCleanup(String who, String what)3196 final void scheduleFinalCleanup(String who, String what) { 3197 mMainThread.scheduleContextCleanup(this, who, what); 3198 } 3199 performFinalCleanup(String who, String what)3200 final void performFinalCleanup(String who, String what) { 3201 //Log.i(TAG, "Cleanup up context: " + this); 3202 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); 3203 if (mContextType == CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI 3204 && mToken instanceof WindowTokenClient) { 3205 mMainThread.onSystemUiContextCleanup(this); 3206 } 3207 } 3208 3209 @UnsupportedAppUsage getReceiverRestrictedContext()3210 final Context getReceiverRestrictedContext() { 3211 if (mReceiverRestrictedContext != null) { 3212 return mReceiverRestrictedContext; 3213 } 3214 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext()); 3215 } 3216 3217 @UnsupportedAppUsage setOuterContext(@onNull Context context)3218 final void setOuterContext(@NonNull Context context) { 3219 mOuterContext = context; 3220 } 3221 3222 @UnsupportedAppUsage getOuterContext()3223 final Context getOuterContext() { 3224 return mOuterContext; 3225 } 3226 3227 @Override 3228 @UnsupportedAppUsage getActivityToken()3229 public IBinder getActivityToken() { 3230 return mContextType == CONTEXT_TYPE_ACTIVITY ? mToken : null; 3231 } 3232 3233 @Override getWindowContextToken()3234 public IBinder getWindowContextToken() { 3235 switch (mContextType) { 3236 case CONTEXT_TYPE_WINDOW_CONTEXT: 3237 case CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI: 3238 return mToken; 3239 default: 3240 return null; 3241 } 3242 } 3243 checkMode(int mode)3244 private void checkMode(int mode) { 3245 if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) { 3246 if ((mode & MODE_WORLD_READABLE) != 0) { 3247 throw new SecurityException("MODE_WORLD_READABLE no longer supported"); 3248 } 3249 if ((mode & MODE_WORLD_WRITEABLE) != 0) { 3250 throw new SecurityException("MODE_WORLD_WRITEABLE no longer supported"); 3251 } 3252 } 3253 } 3254 3255 @SuppressWarnings("deprecation") setFilePermissionsFromMode(String name, int mode, int extraPermissions)3256 static void setFilePermissionsFromMode(String name, int mode, 3257 int extraPermissions) { 3258 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR 3259 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 3260 |extraPermissions; 3261 if ((mode&MODE_WORLD_READABLE) != 0) { 3262 perms |= FileUtils.S_IROTH; 3263 } 3264 if ((mode&MODE_WORLD_WRITEABLE) != 0) { 3265 perms |= FileUtils.S_IWOTH; 3266 } 3267 if (DEBUG) { 3268 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode) 3269 + ", perms=0x" + Integer.toHexString(perms)); 3270 } 3271 FileUtils.setPermissions(name, perms, -1, -1); 3272 } 3273 makeFilename(File base, String name)3274 private File makeFilename(File base, String name) { 3275 if (name.indexOf(File.separatorChar) < 0) { 3276 final File res = new File(base, name); 3277 // We report as filesystem access here to give us the best shot at 3278 // detecting apps that will pass the path down to native code. 3279 BlockGuard.getVmPolicy().onPathAccess(res.getPath()); 3280 return res; 3281 } 3282 throw new IllegalArgumentException( 3283 "File " + name + " contains a path separator"); 3284 } 3285 3286 /** 3287 * Ensure that given directories exist, trying to create them if missing. If 3288 * unable to create, they are filtered by replacing with {@code null}. 3289 */ ensureExternalDirsExistOrFilter(File[] dirs, boolean tryCreateInProcess)3290 private File[] ensureExternalDirsExistOrFilter(File[] dirs, boolean tryCreateInProcess) { 3291 final StorageManager sm = getSystemService(StorageManager.class); 3292 final File[] result = new File[dirs.length]; 3293 for (int i = 0; i < dirs.length; i++) { 3294 File dir = dirs[i]; 3295 if (!dir.exists()) { 3296 try { 3297 if (!tryCreateInProcess || !dir.mkdirs()) { 3298 // recheck existence in case of cross-process race 3299 if (!dir.exists()) { 3300 // Failing to mkdir() may be okay, since we might not have 3301 // enough permissions; ask vold to create on our behalf. 3302 sm.mkdirs(dir); 3303 } 3304 } 3305 } catch (Exception e) { 3306 Log.w(TAG, "Failed to ensure " + dir + ": " + e); 3307 dir = null; 3308 } 3309 } 3310 if (dir != null && !dir.canWrite()) { 3311 // Older versions of the MediaProvider mainline module had a rare early boot race 3312 // condition where app-private dirs could be created with the wrong permissions; 3313 // fix this up here. This check should be very fast, because dir.exists() above 3314 // will already have loaded the dentry in the cache. 3315 sm.fixupAppDir(dir); 3316 } 3317 result[i] = dir; 3318 } 3319 return result; 3320 } 3321 3322 @Override destroy()3323 public void destroy() { 3324 // The final clean-up is to release BroadcastReceiver registrations. It is called in 3325 // ActivityThread for Activity and Service. For the context, such as WindowContext, 3326 // without lifecycle concept, it should be called once the context is released. 3327 scheduleFinalCleanup(getClass().getName(), getOuterContext().getClass().getSimpleName()); 3328 } 3329 3330 // ---------------------------------------------------------------------- 3331 // ---------------------------------------------------------------------- 3332 // ---------------------------------------------------------------------- 3333 3334 private static final class ApplicationContentResolver extends ContentResolver { 3335 @UnsupportedAppUsage 3336 private final ActivityThread mMainThread; 3337 ApplicationContentResolver(Context context, ActivityThread mainThread)3338 public ApplicationContentResolver(Context context, ActivityThread mainThread) { 3339 super(context); 3340 mMainThread = Objects.requireNonNull(mainThread); 3341 } 3342 3343 @Override 3344 @UnsupportedAppUsage acquireProvider(Context context, String auth)3345 protected IContentProvider acquireProvider(Context context, String auth) { 3346 return mMainThread.acquireProvider(context, 3347 ContentProvider.getAuthorityWithoutUserId(auth), 3348 resolveUserIdFromAuthority(auth), true); 3349 } 3350 3351 @Override acquireExistingProvider(Context context, String auth)3352 protected IContentProvider acquireExistingProvider(Context context, String auth) { 3353 return mMainThread.acquireExistingProvider(context, 3354 ContentProvider.getAuthorityWithoutUserId(auth), 3355 resolveUserIdFromAuthority(auth), true); 3356 } 3357 3358 @Override releaseProvider(IContentProvider provider)3359 public boolean releaseProvider(IContentProvider provider) { 3360 return mMainThread.releaseProvider(provider, true); 3361 } 3362 3363 @Override acquireUnstableProvider(Context c, String auth)3364 protected IContentProvider acquireUnstableProvider(Context c, String auth) { 3365 return mMainThread.acquireProvider(c, 3366 ContentProvider.getAuthorityWithoutUserId(auth), 3367 resolveUserIdFromAuthority(auth), false); 3368 } 3369 3370 @Override releaseUnstableProvider(IContentProvider icp)3371 public boolean releaseUnstableProvider(IContentProvider icp) { 3372 return mMainThread.releaseProvider(icp, false); 3373 } 3374 3375 @Override unstableProviderDied(IContentProvider icp)3376 public void unstableProviderDied(IContentProvider icp) { 3377 mMainThread.handleUnstableProviderDied(icp.asBinder(), true); 3378 } 3379 3380 @Override appNotRespondingViaProvider(IContentProvider icp)3381 public void appNotRespondingViaProvider(IContentProvider icp) { 3382 mMainThread.appNotRespondingViaProvider(icp.asBinder()); 3383 } 3384 3385 /** @hide */ resolveUserIdFromAuthority(String auth)3386 protected int resolveUserIdFromAuthority(String auth) { 3387 return ContentProvider.getUserIdFromAuthority(auth, getUserId()); 3388 } 3389 } 3390 } 3391