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