1 /* 2 * Copyright (C) 2012 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 androidx.core.content; 18 19 import static android.content.Context.ACCESSIBILITY_SERVICE; 20 import static android.content.Context.ACCOUNT_SERVICE; 21 import static android.content.Context.ACTIVITY_SERVICE; 22 import static android.content.Context.ALARM_SERVICE; 23 import static android.content.Context.APPWIDGET_SERVICE; 24 import static android.content.Context.APP_OPS_SERVICE; 25 import static android.content.Context.AUDIO_SERVICE; 26 import static android.content.Context.BATTERY_SERVICE; 27 import static android.content.Context.BLUETOOTH_SERVICE; 28 import static android.content.Context.CAMERA_SERVICE; 29 import static android.content.Context.CAPTIONING_SERVICE; 30 import static android.content.Context.CLIPBOARD_SERVICE; 31 import static android.content.Context.CONNECTIVITY_SERVICE; 32 import static android.content.Context.CONSUMER_IR_SERVICE; 33 import static android.content.Context.DEVICE_POLICY_SERVICE; 34 import static android.content.Context.DISPLAY_SERVICE; 35 import static android.content.Context.DOWNLOAD_SERVICE; 36 import static android.content.Context.DROPBOX_SERVICE; 37 import static android.content.Context.INPUT_METHOD_SERVICE; 38 import static android.content.Context.INPUT_SERVICE; 39 import static android.content.Context.JOB_SCHEDULER_SERVICE; 40 import static android.content.Context.KEYGUARD_SERVICE; 41 import static android.content.Context.LAUNCHER_APPS_SERVICE; 42 import static android.content.Context.LAYOUT_INFLATER_SERVICE; 43 import static android.content.Context.LOCATION_SERVICE; 44 import static android.content.Context.MEDIA_PROJECTION_SERVICE; 45 import static android.content.Context.MEDIA_ROUTER_SERVICE; 46 import static android.content.Context.MEDIA_SESSION_SERVICE; 47 import static android.content.Context.NFC_SERVICE; 48 import static android.content.Context.NOTIFICATION_SERVICE; 49 import static android.content.Context.NSD_SERVICE; 50 import static android.content.Context.POWER_SERVICE; 51 import static android.content.Context.PRINT_SERVICE; 52 import static android.content.Context.RESTRICTIONS_SERVICE; 53 import static android.content.Context.SEARCH_SERVICE; 54 import static android.content.Context.SENSOR_SERVICE; 55 import static android.content.Context.STORAGE_SERVICE; 56 import static android.content.Context.TELECOM_SERVICE; 57 import static android.content.Context.TELEPHONY_SERVICE; 58 import static android.content.Context.TELEPHONY_SUBSCRIPTION_SERVICE; 59 import static android.content.Context.TEXT_SERVICES_MANAGER_SERVICE; 60 import static android.content.Context.TV_INPUT_SERVICE; 61 import static android.content.Context.UI_MODE_SERVICE; 62 import static android.content.Context.USAGE_STATS_SERVICE; 63 import static android.content.Context.USB_SERVICE; 64 import static android.content.Context.USER_SERVICE; 65 import static android.content.Context.VIBRATOR_SERVICE; 66 import static android.content.Context.WALLPAPER_SERVICE; 67 import static android.content.Context.WIFI_P2P_SERVICE; 68 import static android.content.Context.WIFI_SERVICE; 69 import static android.content.Context.WINDOW_SERVICE; 70 71 import android.accounts.AccountManager; 72 import android.annotation.SuppressLint; 73 import android.app.Activity; 74 import android.app.ActivityManager; 75 import android.app.AlarmManager; 76 import android.app.AppOpsManager; 77 import android.app.DownloadManager; 78 import android.app.KeyguardManager; 79 import android.app.NotificationManager; 80 import android.app.SearchManager; 81 import android.app.UiModeManager; 82 import android.app.WallpaperManager; 83 import android.app.admin.DevicePolicyManager; 84 import android.app.job.JobScheduler; 85 import android.app.usage.UsageStatsManager; 86 import android.appwidget.AppWidgetManager; 87 import android.bluetooth.BluetoothManager; 88 import android.content.BroadcastReceiver; 89 import android.content.ClipboardManager; 90 import android.content.ComponentName; 91 import android.content.Context; 92 import android.content.Intent; 93 import android.content.IntentFilter; 94 import android.content.RestrictionsManager; 95 import android.content.pm.ApplicationInfo; 96 import android.content.pm.LauncherApps; 97 import android.content.pm.PackageManager; 98 import android.content.res.ColorStateList; 99 import android.content.res.Configuration; 100 import android.graphics.drawable.Drawable; 101 import android.hardware.ConsumerIrManager; 102 import android.hardware.SensorManager; 103 import android.hardware.camera2.CameraManager; 104 import android.hardware.display.DisplayManager; 105 import android.hardware.input.InputManager; 106 import android.hardware.usb.UsbManager; 107 import android.location.LocationManager; 108 import android.media.AudioManager; 109 import android.media.MediaRouter; 110 import android.media.projection.MediaProjectionManager; 111 import android.media.session.MediaSessionManager; 112 import android.media.tv.TvInputManager; 113 import android.net.ConnectivityManager; 114 import android.net.nsd.NsdManager; 115 import android.net.wifi.WifiManager; 116 import android.net.wifi.p2p.WifiP2pManager; 117 import android.nfc.NfcManager; 118 import android.os.BatteryManager; 119 import android.os.Build; 120 import android.os.Bundle; 121 import android.os.DropBoxManager; 122 import android.os.Handler; 123 import android.os.PowerManager; 124 import android.os.Process; 125 import android.os.StatFs; 126 import android.os.UserManager; 127 import android.os.Vibrator; 128 import android.os.storage.StorageManager; 129 import android.print.PrintManager; 130 import android.telecom.TelecomManager; 131 import android.telephony.SubscriptionManager; 132 import android.telephony.TelephonyManager; 133 import android.text.TextUtils; 134 import android.util.Log; 135 import android.view.Display; 136 import android.view.LayoutInflater; 137 import android.view.WindowManager; 138 import android.view.accessibility.AccessibilityManager; 139 import android.view.accessibility.CaptioningManager; 140 import android.view.inputmethod.InputMethodManager; 141 import android.view.textservice.TextServicesManager; 142 143 import androidx.annotation.ColorInt; 144 import androidx.annotation.ColorRes; 145 import androidx.annotation.DisplayContext; 146 import androidx.annotation.DrawableRes; 147 import androidx.annotation.IntDef; 148 import androidx.annotation.RequiresApi; 149 import androidx.annotation.RestrictTo; 150 import androidx.core.app.ActivityOptionsCompat; 151 import androidx.core.app.LocaleManagerCompat; 152 import androidx.core.app.NotificationManagerCompat; 153 import androidx.core.content.res.ResourcesCompat; 154 import androidx.core.os.ConfigurationCompat; 155 import androidx.core.os.EnvironmentCompat; 156 import androidx.core.os.ExecutorCompat; 157 import androidx.core.os.LocaleListCompat; 158 import androidx.core.util.ObjectsCompat; 159 160 import org.jspecify.annotations.NonNull; 161 import org.jspecify.annotations.Nullable; 162 163 import java.io.File; 164 import java.lang.annotation.Retention; 165 import java.lang.annotation.RetentionPolicy; 166 import java.util.HashMap; 167 import java.util.concurrent.Executor; 168 169 /** 170 * Helper for accessing features in {@link Context}. 171 */ 172 @SuppressLint("PrivateConstructorForUtilityClass") // Already launched with public constructor 173 public class ContextCompat { 174 private static final String TAG = "ContextCompat"; 175 176 // Lock that provides similar functionality to ContextImpl.mSync. 177 private static final Object sSync = new Object(); 178 179 /** 180 * This class should not be instantiated, but the constructor must be 181 * visible for the class to be extended (ex. in ActivityCompat). 182 */ ContextCompat()183 protected ContextCompat() { 184 // Not publicly instantiable, but may be extended. 185 } 186 187 private static final String DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION_SUFFIX = 188 ".DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"; 189 190 191 @RestrictTo(RestrictTo.Scope.LIBRARY) 192 @IntDef(flag = true, value = { 193 RECEIVER_VISIBLE_TO_INSTANT_APPS, RECEIVER_EXPORTED, RECEIVER_NOT_EXPORTED, 194 }) 195 @Retention(RetentionPolicy.SOURCE) 196 public @interface RegisterReceiverFlags {} 197 /** 198 * Flag for {@link #registerReceiver}: The receiver can receive broadcasts from Instant Apps. 199 */ 200 public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 0x1; 201 202 /** 203 * Flag for {@link #registerReceiver}: The receiver can receive broadcasts from other Apps. 204 * Has the same behavior as marking a statically registered receiver with "exported=true" 205 */ 206 public static final int RECEIVER_EXPORTED = 0x2; 207 208 /** 209 * Flag for {@link #registerReceiver}: The receiver cannot receive broadcasts from other Apps. 210 * Has the same behavior as marking a statically registered receiver with "exported=false" 211 */ 212 public static final int RECEIVER_NOT_EXPORTED = 0x4; 213 214 /** 215 * Start a set of activities as a synthesized task stack, if able. 216 * 217 * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for 218 * app navigation using the back key changed. The back key's behavior is local 219 * to the current task and does not capture navigation across different tasks. 220 * Navigating across tasks and easily reaching the previous task is accomplished 221 * through the "recents" UI, accessible through the software-provided Recents key 222 * on the navigation or system bar. On devices with the older hardware button configuration 223 * the recents UI can be accessed with a long press on the Home key.</p> 224 * 225 * <p>When crossing from one task stack to another post-Android 3.0, 226 * the application should synthesize a back stack/history for the new task so that 227 * the user may navigate out of the new task and back to the Launcher by repeated 228 * presses of the back key. Back key presses should not navigate across task stacks.</p> 229 * 230 * <p>startActivities provides a mechanism for constructing a synthetic task stack of 231 * multiple activities. If the underlying API is not available on the system this method 232 * will return false.</p> 233 * 234 * @param context Start activities using this activity as the starting context 235 * @param intents Array of intents defining the activities that will be started. The element 236 * length-1 will correspond to the top activity on the resulting task stack. 237 * @return true if the underlying API was available and the call was successful, false otherwise 238 */ startActivities(@onNull Context context, Intent @NonNull [] intents)239 public static boolean startActivities(@NonNull Context context, Intent @NonNull [] intents) { 240 return startActivities(context, intents, null); 241 } 242 243 /** 244 * Start a set of activities as a synthesized task stack, if able. 245 * 246 * <p>In API level 11 (Android 3.0/Honeycomb) the recommended conventions for 247 * app navigation using the back key changed. The back key's behavior is local 248 * to the current task and does not capture navigation across different tasks. 249 * Navigating across tasks and easily reaching the previous task is accomplished 250 * through the "recents" UI, accessible through the software-provided Recents key 251 * on the navigation or system bar. On devices with the older hardware button configuration 252 * the recents UI can be accessed with a long press on the Home key.</p> 253 * 254 * <p>When crossing from one task stack to another post-Android 3.0, 255 * the application should synthesize a back stack/history for the new task so that 256 * the user may navigate out of the new task and back to the Launcher by repeated 257 * presses of the back key. Back key presses should not navigate across task stacks.</p> 258 * 259 * <p>startActivities provides a mechanism for constructing a synthetic task stack of 260 * multiple activities. If the underlying API is not available on the system this method 261 * will return false.</p> 262 * 263 * @param context Start activities using this activity as the starting context 264 * @param intents Array of intents defining the activities that will be started. The element 265 * length-1 will correspond to the top activity on the resulting task stack. 266 * @param options Additional options for how the Activity should be started. 267 * See {@link Context#startActivity(Intent, Bundle)} 268 * @return true if the underlying API was available and the call was successful, false otherwise 269 */ startActivities(@onNull Context context, Intent @NonNull [] intents, @Nullable Bundle options)270 public static boolean startActivities(@NonNull Context context, Intent @NonNull [] intents, 271 @Nullable Bundle options) { 272 context.startActivities(intents, options); 273 return true; 274 } 275 276 /** 277 * Start an activity with additional launch information, if able. 278 * 279 * <p>In Android 4.1+ additional options were introduced to allow for more 280 * control on activity launch animations. Applications can use this method 281 * along with {@link ActivityOptionsCompat} to use these animations when 282 * available. When run on versions of the platform where this feature does 283 * not exist the activity will be launched normally.</p> 284 * 285 * @param context Context to launch activity from. 286 * @param intent The description of the activity to start. 287 * @param options Additional options for how the Activity should be started. 288 * May be null if there are no options. See 289 * {@link ActivityOptionsCompat} for how to build the Bundle 290 * supplied here; there are no supported definitions for 291 * building it manually. 292 * @deprecated Call {@link Context#startActivity()} directly. 293 */ 294 @Deprecated 295 @androidx.annotation.ReplaceWith(expression = "context.startActivity(intent, options)") startActivity(@onNull Context context, @NonNull Intent intent, @Nullable Bundle options)296 public static void startActivity(@NonNull Context context, @NonNull Intent intent, 297 @Nullable Bundle options) { 298 context.startActivity(intent, options); 299 } 300 301 /** 302 * Returns the absolute path to the directory on the filesystem where all 303 * private files belonging to this app are stored. Apps should not use this 304 * path directly; they should instead use {@link Context#getFilesDir()}, 305 * {@link Context#getCacheDir()}, {@link Context#getDir(String, int)}, or 306 * other storage APIs on {@link Context}. 307 * <p> 308 * The returned path may change over time if the calling app is moved to an 309 * adopted storage device, so only relative paths should be persisted. 310 * <p> 311 * No additional permissions are required for the calling app to read or 312 * write files under the returned path. 313 * 314 * @see ApplicationInfo#dataDir 315 */ getDataDir(@onNull Context context)316 public static @Nullable File getDataDir(@NonNull Context context) { 317 if (Build.VERSION.SDK_INT >= 24) { 318 return Api24Impl.getDataDir(context); 319 } else { 320 final String dataDir = context.getApplicationInfo().dataDir; 321 return dataDir != null ? new File(dataDir) : null; 322 } 323 } 324 325 /** 326 * Returns absolute paths to application-specific directories on all 327 * external storage devices where the application's OBB files (if there are 328 * any) can be found. Note if the application does not have any OBB files, 329 * these directories may not exist. 330 * <p> 331 * This is like {@link Context#getFilesDir()} in that these files will be 332 * deleted when the application is uninstalled, however there are some 333 * important differences: 334 * <ul> 335 * <li>External files are not always available: they will disappear if the 336 * user mounts the external storage on a computer or removes it. 337 * <li>There is no security enforced with these files. 338 * </ul> 339 * <p> 340 * External storage devices returned here are considered a permanent part of 341 * the device, including both emulated external storage and physical media 342 * slots, such as SD cards in a battery compartment. The returned paths do 343 * not include transient devices, such as USB flash drives. 344 * <p> 345 * An application may store data on any or all of the returned devices. For 346 * example, an app may choose to store large files on the device with the 347 * most available space, as measured by {@link StatFs}. 348 * <p> 349 * Starting in {@link Build.VERSION_CODES#KITKAT}, no permissions 350 * are required to write to the returned paths; they're always accessible to 351 * the calling app. Before then, 352 * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to 353 * write. Write access outside of these paths on secondary external storage 354 * devices is not available. To request external storage access in a 355 * backwards compatible way, consider using {@code android:maxSdkVersion} 356 * like this: 357 * 358 * <pre class="prettyprint"><uses-permission 359 * android:name="android.permission.WRITE_EXTERNAL_STORAGE" 360 * android:maxSdkVersion="18" /></pre> 361 * <p> 362 * The first path returned is the same as {@link Context#getObbDir()}. 363 * Returned paths may be {@code null} if a storage device is unavailable. 364 * 365 * @see Context#getObbDir() 366 * @see EnvironmentCompat#getStorageState(File) 367 * @deprecated Call {@link Context#getObbDirs()} directly. 368 */ 369 @Deprecated 370 @androidx.annotation.ReplaceWith(expression = "context.getObbDirs()") getObbDirs(@onNull Context context)371 public static File @NonNull [] getObbDirs(@NonNull Context context) { 372 return context.getObbDirs(); 373 } 374 375 /** 376 * Returns absolute paths to application-specific directories on all 377 * external storage devices where the application can place persistent files 378 * it owns. These files are internal to the application, and not typically 379 * visible to the user as media. 380 * <p> 381 * This is like {@link Context#getFilesDir()} in that these files will be 382 * deleted when the application is uninstalled, however there are some 383 * important differences: 384 * <ul> 385 * <li>External files are not always available: they will disappear if the 386 * user mounts the external storage on a computer or removes it. 387 * <li>There is no security enforced with these files. 388 * </ul> 389 * <p> 390 * External storage devices returned here are considered a permanent part of 391 * the device, including both emulated external storage and physical media 392 * slots, such as SD cards in a battery compartment. The returned paths do 393 * not include transient devices, such as USB flash drives. 394 * <p> 395 * An application may store data on any or all of the returned devices. For 396 * example, an app may choose to store large files on the device with the 397 * most available space, as measured by {@link StatFs}. 398 * <p> 399 * Starting in {@link Build.VERSION_CODES#KITKAT}, no permissions 400 * are required to write to the returned paths; they're always accessible to 401 * the calling app. Before then, 402 * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to 403 * write. Write access outside of these paths on secondary external storage 404 * devices is not available. To request external storage access in a 405 * backwards compatible way, consider using {@code android:maxSdkVersion} 406 * like this: 407 * 408 * <pre class="prettyprint"><uses-permission 409 * android:name="android.permission.WRITE_EXTERNAL_STORAGE" 410 * android:maxSdkVersion="18" /></pre> 411 * <p> 412 * The first path returned is the same as 413 * {@link Context#getExternalFilesDir(String)}. Returned paths may be 414 * {@code null} if a storage device is unavailable. 415 * 416 * @see Context#getExternalFilesDir(String) 417 * @see EnvironmentCompat#getStorageState(File) 418 * @deprecated Call {@link Context#getExternalFilesDirs()} directly. 419 */ 420 @Deprecated 421 @androidx.annotation.ReplaceWith(expression = "context.getExternalFilesDirs(type)") getExternalFilesDirs(@onNull Context context, @Nullable String type)422 public static File @NonNull [] getExternalFilesDirs(@NonNull Context context, 423 @Nullable String type) { 424 return context.getExternalFilesDirs(type); 425 } 426 427 /** 428 * Returns absolute paths to application-specific directories on all 429 * external storage devices where the application can place cache files it 430 * owns. These files are internal to the application, and not typically 431 * visible to the user as media. 432 * <p> 433 * This is like {@link Context#getCacheDir()} in that these files will be 434 * deleted when the application is uninstalled, however there are some 435 * important differences: 436 * <ul> 437 * <li>External files are not always available: they will disappear if the 438 * user mounts the external storage on a computer or removes it. 439 * <li>There is no security enforced with these files. 440 * </ul> 441 * <p> 442 * External storage devices returned here are considered a permanent part of 443 * the device, including both emulated external storage and physical media 444 * slots, such as SD cards in a battery compartment. The returned paths do 445 * not include transient devices, such as USB flash drives. 446 * <p> 447 * An application may store data on any or all of the returned devices. For 448 * example, an app may choose to store large files on the device with the 449 * most available space, as measured by {@link StatFs}. 450 * <p> 451 * Starting in {@link Build.VERSION_CODES#KITKAT}, no permissions 452 * are required to write to the returned paths; they're always accessible to 453 * the calling app. Before then, 454 * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} is required to 455 * write. Write access outside of these paths on secondary external storage 456 * devices is not available. To request external storage access in a 457 * backwards compatible way, consider using {@code android:maxSdkVersion} 458 * like this: 459 * 460 * <pre class="prettyprint"><uses-permission 461 * android:name="android.permission.WRITE_EXTERNAL_STORAGE" 462 * android:maxSdkVersion="18" /></pre> 463 * <p> 464 * The first path returned is the same as 465 * {@link Context#getExternalCacheDir()}. Returned paths may be {@code null} 466 * if a storage device is unavailable. 467 * 468 * @see Context#getExternalCacheDir() 469 * @see EnvironmentCompat#getStorageState(File) 470 * @deprecated Call {@link Context#getExternalCacheDirs()} directly. 471 */ 472 @Deprecated 473 @androidx.annotation.ReplaceWith(expression = "context.getExternalCacheDirs()") getExternalCacheDirs(@onNull Context context)474 public static File @NonNull [] getExternalCacheDirs(@NonNull Context context) { 475 return context.getExternalCacheDirs(); 476 } 477 478 /** 479 * Returns a drawable object associated with a particular resource ID. 480 * <p> 481 * Starting in {@link Build.VERSION_CODES#LOLLIPOP}, the 482 * returned drawable will be styled for the specified Context's theme. 483 * 484 * @param context context to use for getting the drawable. 485 * @param id The desired resource identifier, as generated by the aapt tool. 486 * This integer encodes the package, type, and resource entry. 487 * The value 0 is an invalid identifier. 488 * @return Drawable An object that can be used to draw this resource. 489 */ 490 @SuppressWarnings("deprecation") getDrawable(@onNull Context context, @DrawableRes int id)491 public static @Nullable Drawable getDrawable(@NonNull Context context, @DrawableRes int id) { 492 if (Build.VERSION.SDK_INT >= 21) { 493 return Api21Impl.getDrawable(context, id); 494 } else { 495 return context.getResources().getDrawable(id); 496 } 497 } 498 499 /** 500 * Returns a color state list associated with a particular resource ID. 501 * <p> 502 * Starting in {@link Build.VERSION_CODES#M}, the returned 503 * color state list will be styled for the specified Context's theme. 504 * 505 * @param context context to use for getting the color state list. 506 * @param id The desired resource identifier, as generated by the aapt 507 * tool. This integer encodes the package, type, and resource 508 * entry. The value 0 is an invalid identifier. 509 * @return A color state list, or {@code null} if the resource could not be 510 * resolved. 511 * @throws android.content.res.Resources.NotFoundException if the given ID 512 * does not exist. 513 */ getColorStateList(@onNull Context context, @ColorRes int id)514 public static @Nullable ColorStateList getColorStateList(@NonNull Context context, 515 @ColorRes int id) { 516 return ResourcesCompat.getColorStateList(context.getResources(), id, context.getTheme()); 517 } 518 519 /** 520 * Returns a color associated with a particular resource ID 521 * <p> 522 * Starting in {@link Build.VERSION_CODES#M}, the returned 523 * color will be styled for the specified Context's theme. 524 * 525 * @param context context to use for getting the color. 526 * @param id The desired resource identifier, as generated by the aapt 527 * tool. This integer encodes the package, type, and resource 528 * entry. The value 0 is an invalid identifier. 529 * @return A single color value in the form 0xAARRGGBB. 530 * @throws android.content.res.Resources.NotFoundException if the given ID 531 * does not exist. 532 */ 533 @SuppressWarnings("deprecation") 534 @ColorInt getColor(@onNull Context context, @ColorRes int id)535 public static int getColor(@NonNull Context context, @ColorRes int id) { 536 if (Build.VERSION.SDK_INT >= 23) { 537 return Api23Impl.getColor(context, id); 538 } else { 539 return context.getResources().getColor(id); 540 } 541 } 542 543 /** 544 * Determine whether <em>you</em> have been granted a particular permission. 545 * 546 * @param context context for which to check the permission. 547 * @param permission The name of the permission being checked. 548 * @return {@link PackageManager#PERMISSION_GRANTED} if you have the 549 * permission, or {@link PackageManager#PERMISSION_DENIED} if not. 550 * @see PackageManager#checkPermission(String, String) 551 */ checkSelfPermission(@onNull Context context, @NonNull String permission)552 public static int checkSelfPermission(@NonNull Context context, @NonNull String permission) { 553 ObjectsCompat.requireNonNull(permission, "permission must be non-null"); 554 if (Build.VERSION.SDK_INT < 33 555 && TextUtils.equals(android.Manifest.permission.POST_NOTIFICATIONS, permission)) { 556 return NotificationManagerCompat.from(context).areNotificationsEnabled() 557 ? PackageManager.PERMISSION_GRANTED 558 : PackageManager.PERMISSION_DENIED; 559 } 560 return context.checkPermission(permission, Process.myPid(), Process.myUid()); 561 } 562 563 /** 564 * Returns the absolute path to the directory on the filesystem similar to 565 * {@link Context#getFilesDir()}. The difference is that files placed under this 566 * directory will be excluded from automatic backup to remote storage on 567 * devices running {@link Build.VERSION_CODES#LOLLIPOP} or later. 568 * 569 * <p>No permissions are required to read or write to the returned path, since this 570 * path is internal storage. 571 * 572 * @return The path of the directory holding application files that will not be 573 * automatically backed up to remote storage. 574 * @see Context#getFilesDir() 575 */ getNoBackupFilesDir(@onNull Context context)576 public static @Nullable File getNoBackupFilesDir(@NonNull Context context) { 577 if (Build.VERSION.SDK_INT >= 21) { 578 return Api21Impl.getNoBackupFilesDir(context); 579 } else { 580 ApplicationInfo appInfo = context.getApplicationInfo(); 581 return createFilesDir(new File(appInfo.dataDir, "no_backup")); 582 } 583 } 584 585 /** 586 * Returns the absolute path to the application specific cache directory on 587 * the filesystem designed for storing cached code. On devices running 588 * {@link Build.VERSION_CODES#LOLLIPOP} or later, the system will delete 589 * any files stored in this location both when your specific application is 590 * upgraded, and when the entire platform is upgraded. 591 * <p> 592 * This location is optimal for storing compiled or optimized code generated 593 * by your application at runtime. 594 * <p> 595 * Apps require no extra permissions to read or write to the returned path, 596 * since this path lives in their private storage. 597 * 598 * @return The path of the directory holding application code cache files. 599 */ getCodeCacheDir(@onNull Context context)600 public static @NonNull File getCodeCacheDir(@NonNull Context context) { 601 if (Build.VERSION.SDK_INT >= 21) { 602 return Api21Impl.getCodeCacheDir(context); 603 } else { 604 ApplicationInfo appInfo = context.getApplicationInfo(); 605 return createFilesDir(new File(appInfo.dataDir, "code_cache")); 606 } 607 } 608 createFilesDir(File file)609 private static File createFilesDir(File file) { 610 // In the platform, all operations on Context that involve creating files (codeCacheDir, 611 // noBackupFilesDir, etc.) are synchronized on a single lock owned by the Context. So, if 612 // we lock on a single static lock owned by ContextCompat then we're a bit too broad but 613 // at least we'll provide similar guarantees. 614 synchronized (sSync) { 615 if (!file.exists()) { 616 if (file.mkdirs()) { 617 return file; 618 } else { 619 // There used to be another check for file.exists() here, but that was a 620 // side-effect of improper synchronization. 621 Log.w(TAG, "Unable to create files subdir " + file.getPath()); 622 } 623 } 624 return file; 625 } 626 } 627 628 /** 629 * Return a new Context object for the current Context but whose storage 630 * APIs are backed by device-protected storage. 631 * <p> 632 * On devices with direct boot, data stored in this location is encrypted 633 * with a key tied to the physical device, and it can be accessed 634 * immediately after the device has booted successfully, both 635 * <em>before and after</em> the user has authenticated with their 636 * credentials (such as a lock pattern or PIN). 637 * <p> 638 * Because device-protected data is available without user authentication, 639 * you should carefully limit the data you store using this Context. For 640 * example, storing sensitive authentication tokens or passwords in the 641 * device-protected area is strongly discouraged. 642 * <p> 643 * If the underlying device does not have the ability to store 644 * device-protected and credential-protected data using different keys, then 645 * both storage areas will become available at the same time. They remain as 646 * two distinct storage locations on disk, and only the window of 647 * availability changes. 648 * <p> 649 * Each call to this method returns a new instance of a Context object; 650 * Context objects are not shared, however common state (ClassLoader, other 651 * Resources for the same configuration) may be so the Context itself can be 652 * fairly lightweight. 653 * <p> 654 * Prior to API 24 this method returns 655 * {@code null}, since device-protected storage is not available. 656 * 657 * @see ContextCompat#isDeviceProtectedStorage(Context) 658 */ createDeviceProtectedStorageContext(@onNull Context context)659 public static @Nullable Context createDeviceProtectedStorageContext(@NonNull Context context) { 660 if (Build.VERSION.SDK_INT >= 24) { 661 return Api24Impl.createDeviceProtectedStorageContext(context); 662 } else { 663 return null; 664 } 665 } 666 667 /** 668 * Indicates if the storage APIs of this Context are backed by 669 * device-encrypted storage. 670 * 671 * @see ContextCompat#createDeviceProtectedStorageContext(Context) 672 */ isDeviceProtectedStorage(@onNull Context context)673 public static boolean isDeviceProtectedStorage(@NonNull Context context) { 674 if (Build.VERSION.SDK_INT >= 24) { 675 return Api24Impl.isDeviceProtectedStorage(context); 676 } else { 677 return false; 678 } 679 } 680 681 /** 682 * Return an {@link Executor} that will run enqueued tasks on the main 683 * thread associated with this context. This is the thread used to dispatch 684 * calls to application components (activities, services, etc). 685 */ getMainExecutor(@onNull Context context)686 public static @NonNull Executor getMainExecutor(@NonNull Context context) { 687 if (Build.VERSION.SDK_INT >= 28) { 688 return Api28Impl.getMainExecutor(context); 689 } 690 return ExecutorCompat.create(new Handler(context.getMainLooper())); 691 } 692 693 /** 694 * startForegroundService() was introduced in O, just call startService 695 * for before O. 696 * 697 * @param context Context to start Service from. 698 * @param intent The description of the Service to start. 699 * @see Context#startForegroundService(Intent) 700 * @see Context#startService(Intent) 701 */ startForegroundService(@onNull Context context, @NonNull Intent intent)702 public static void startForegroundService(@NonNull Context context, @NonNull Intent intent) { 703 if (Build.VERSION.SDK_INT >= 26) { 704 Api26Impl.startForegroundService(context, intent); 705 } else { 706 // Pre-O behavior. 707 context.startService(intent); 708 } 709 } 710 711 /** 712 * Get the display this context is associated with or the 713 * {@link Display#DEFAULT_DISPLAY default display} as the fallback if the context is not 714 * associated with any {@link Display}. 715 * <p> 716 * Applications must use this method with {@link Activity} or a context associated with a 717 * {@link Display} via {@link Context#createDisplayContext(Display)} or 718 * {@link Context#createWindowContext(Display, int, Bundle)}, or the reported {@link Display} 719 * instance is not reliable. </p> 720 * 721 * @param context Context to obtain the associated display 722 * @return The display associated with the Context or the default display if the context 723 * doesn't associated with any display. 724 */ getDisplayOrDefault(@isplayContext @onNull Context context)725 public static @NonNull Display getDisplayOrDefault(@DisplayContext @NonNull Context context) { 726 if (Build.VERSION.SDK_INT >= 30) { 727 return Api30Impl.getDisplayOrDefault(context); 728 } else { 729 final WindowManager windowManager = 730 (WindowManager) context.getSystemService(WINDOW_SERVICE); 731 return windowManager.getDefaultDisplay(); 732 } 733 } 734 735 /** 736 * Return the handle to a system-level service by class. 737 * 738 * @param context Context to retrieve service from. 739 * @param serviceClass The class of the desired service. 740 * @return The service or null if the class is not a supported system service. 741 * @see Context#getSystemService(Class) 742 */ 743 @SuppressWarnings("unchecked") getSystemService(@onNull Context context, @NonNull Class<T> serviceClass)744 public static <T> @Nullable T getSystemService(@NonNull Context context, 745 @NonNull Class<T> serviceClass) { 746 if (Build.VERSION.SDK_INT >= 23) { 747 return Api23Impl.getSystemService(context, serviceClass); 748 } 749 750 String serviceName = getSystemServiceName(context, serviceClass); 751 return serviceName != null ? (T) context.getSystemService(serviceName) : null; 752 } 753 754 /** 755 * Register a broadcast receiver. 756 * 757 * @param context Context to retrieve service from. 758 * @param receiver The BroadcastReceiver to handle the broadcast. 759 * @param filter Selects the Intent broadcasts to be received. 760 * @param flags If this receiver is listening for broadcasts sent from other apps—even other 761 * apps that you own—use the {@link #RECEIVER_EXPORTED} flag. If instead this 762 * receiver is listening only for broadcasts sent by your 763 * app, or from the system UID, use the {@link #RECEIVER_NOT_EXPORTED} flag. 764 * @return The first sticky intent found that matches <var>filter</var>, 765 * or null if there are none. 766 * @see Context#registerReceiver(BroadcastReceiver, IntentFilter, int) 767 * @see https://developer.android.com/develop/background-work/background-tasks/broadcasts#context-registered-receivers 768 */ registerReceiver(@onNull Context context, @Nullable BroadcastReceiver receiver, @NonNull IntentFilter filter, @RegisterReceiverFlags int flags)769 public static @Nullable Intent registerReceiver(@NonNull Context context, 770 @Nullable BroadcastReceiver receiver, @NonNull IntentFilter filter, 771 @RegisterReceiverFlags int flags) { 772 return registerReceiver(context, receiver, filter, null, null, flags); 773 } 774 775 /** 776 * Register a broadcast receiver. 777 * 778 * @param context Context to retrieve service from. 779 * @param receiver The BroadcastReceiver to handle the broadcast. 780 * @param filter Selects the Intent broadcasts to be received. 781 * @param broadcastPermission String naming a permission that a broadcaster must hold in 782 * order to send and Intent to you. If null, no permission is 783 * required. 784 * @param scheduler Handler identifying the thread will receive the Intent. If 785 * null, the main thread of the process will be used. 786 * @param flags If this receiver is listening for broadcasts sent from other 787 * apps—even other apps that you own—use the 788 * {@link #RECEIVER_EXPORTED} flag. If instead this receiver is 789 * listening only for broadcasts sent by your app, or from the 790 * system UID, use the {@link #RECEIVER_NOT_EXPORTED} flag. 791 * @return The first sticky intent found that matches <var>filter</var>, 792 * or null if there are none. 793 * @see Context#registerReceiver(BroadcastReceiver, IntentFilter, String, Handler, int) 794 * @see https://developer.android.com/develop/background-work/background-tasks/broadcasts#context-registered-receivers 795 */ registerReceiver(@onNull Context context, @Nullable BroadcastReceiver receiver, @NonNull IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler, @RegisterReceiverFlags int flags)796 public static @Nullable Intent registerReceiver(@NonNull Context context, 797 @Nullable BroadcastReceiver receiver, @NonNull IntentFilter filter, 798 @Nullable String broadcastPermission, 799 @Nullable Handler scheduler, @RegisterReceiverFlags int flags) { 800 if (((flags & RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0) && ((flags & RECEIVER_NOT_EXPORTED) 801 != 0)) { 802 throw new IllegalArgumentException("Cannot specify both " 803 + "RECEIVER_VISIBLE_TO_INSTANT_APPS and RECEIVER_NOT_EXPORTED"); 804 } 805 806 if ((flags & RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0) { 807 flags |= RECEIVER_EXPORTED; 808 } 809 810 if (((flags & RECEIVER_EXPORTED) == 0) && ((flags & RECEIVER_NOT_EXPORTED) == 0)) { 811 throw new IllegalArgumentException("One of either RECEIVER_EXPORTED or " 812 + "RECEIVER_NOT_EXPORTED is required"); 813 } 814 815 if (((flags & RECEIVER_EXPORTED) != 0) && ((flags & RECEIVER_NOT_EXPORTED) != 0)) { 816 throw new IllegalArgumentException("Cannot specify both RECEIVER_EXPORTED and " 817 + "RECEIVER_NOT_EXPORTED"); 818 } 819 820 if (Build.VERSION.SDK_INT >= 33) { 821 return Api33Impl.registerReceiver(context, receiver, filter, broadcastPermission, 822 scheduler, flags); 823 } 824 if (Build.VERSION.SDK_INT >= 26) { 825 return Api26Impl.registerReceiver(context, receiver, filter, broadcastPermission, 826 scheduler, flags); 827 } 828 if (((flags & RECEIVER_NOT_EXPORTED) != 0) && (broadcastPermission == null)) { 829 String permission = obtainAndCheckReceiverPermission(context); 830 return context.registerReceiver(receiver, filter, permission, scheduler /* handler */); 831 } 832 return context.registerReceiver(receiver, filter, broadcastPermission, 833 scheduler); 834 } 835 836 /** 837 * Gets the name of the system-level service that is represented by the specified class. 838 * 839 * @param context Context to retrieve service name from. 840 * @param serviceClass The class of the desired service. 841 * @return The service name or null if the class is not a supported system service. 842 * @see Context#getSystemServiceName(Class) 843 */ getSystemServiceName(@onNull Context context, @NonNull Class<?> serviceClass)844 public static @Nullable String getSystemServiceName(@NonNull Context context, 845 @NonNull Class<?> serviceClass) { 846 if (Build.VERSION.SDK_INT >= 23) { 847 return Api23Impl.getSystemServiceName(context, serviceClass); 848 } 849 return LegacyServiceMapHolder.SERVICES.get(serviceClass); 850 } 851 852 /** 853 * Gets the resource string that also respects the per-app locales. If developers set the 854 * per-app locales via 855 * {@link androidx.appcompat.app.AppCompatDelegate#setApplicationLocales(LocaleListCompat)}, 856 * this API returns localized strings even if the context is not 857 * {@link androidx.appcompat.app.AppCompatActivity}. 858 * 859 * <p> 860 * Compatibility behavior: 861 * <ul> 862 * <li>API 17 and above, this method return the localized string that respects per-app 863 * locales.</li> 864 * <li>API 16 and earlier, this method directly return the result of 865 * {@link Context#getString(int)}</li> 866 * </ul> 867 * </p> 868 */ getString(@onNull Context context, int resId)869 public static @NonNull String getString(@NonNull Context context, int resId) { 870 return getContextForLanguage(context).getString(resId); 871 } 872 873 /** 874 * Gets the context which respects the per-app locales locale. This API is specifically for 875 * developers who set the per-app locales via 876 * {@link androidx.appcompat.app.AppCompatDelegate#setApplicationLocales(LocaleListCompat)}, 877 * but who needs to use the context out of {@link androidx.appcompat.app.AppCompatActivity} 878 * scope. 879 * 880 * <p>The developers can override the returned context in Application's 881 * {@link android.content.ContextWrapper#attachBaseContext(Context)}, so that developers can 882 * get the localized string via application's context.</p> 883 * 884 * <p> 885 * Compatibility behavior: 886 * <ul> 887 * <li>API 17 and above, the locale in the context returned by this method will respect the 888 * the per-app locale.</li> 889 * <li>API 16 and earlier, this method directly return the {@link Context}</li> 890 * </ul> 891 * </p> 892 */ getContextForLanguage(@onNull Context context)893 public static @NonNull Context getContextForLanguage(@NonNull Context context) { 894 LocaleListCompat locales = LocaleManagerCompat.getApplicationLocales(context); 895 896 // The Android framework supports per-app locales on API 33, so we assume the 897 // configuration has been updated after API 32. 898 if (Build.VERSION.SDK_INT <= 32) { 899 if (!locales.isEmpty()) { 900 Configuration newConfig = new Configuration( 901 context.getResources().getConfiguration()); 902 ConfigurationCompat.setLocales(newConfig, locales); 903 return context.createConfigurationContext(newConfig); 904 } 905 } 906 return context; 907 } 908 909 /** 910 * Attribution can be used in complex apps to logically separate parts of the app. E.g. a 911 * blogging app might also have a instant messaging app built in. In this case two separate tags 912 * can for used each sub-feature. 913 * <p> 914 * Compatibility behavior: 915 * <ul> 916 * <li>API 30 and above, returns the attribution tag or {@code null} 917 * <li>API 29 and earlier, returns {@code null} 918 * </ul> 919 * 920 * @return the attribution tag this context is for or {@code null} if this is the default. 921 */ getAttributionTag(@onNull Context context)922 public static @Nullable String getAttributionTag(@NonNull Context context) { 923 if (Build.VERSION.SDK_INT >= 30) { 924 return Api30Impl.getAttributionTag(context); 925 } 926 927 return null; 928 } 929 930 /** 931 * Return a new Context object for the current Context but attribute to a different tag. 932 * In complex apps attribution tagging can be used to distinguish between separate logical 933 * parts. 934 * <p> 935 * Compatibility behavior: 936 * <ul> 937 * <li>API 30 and above, returns a new Context object with the specified attribution tag 938 * <li>API 29 and earlier, returns the original {@code context} with no attribution tag 939 * </ul> 940 * 941 * @param context The current context. 942 * @param attributionTag The tag or {@code null} to create a context for the default. 943 * @return A {@link Context} that is tagged for the new attribution 944 * @see #getAttributionTag(Context) 945 */ createAttributionContext(@onNull Context context, @Nullable String attributionTag)946 public static @NonNull Context createAttributionContext(@NonNull Context context, 947 @Nullable String attributionTag) { 948 if (Build.VERSION.SDK_INT >= 30) { 949 return Api30Impl.createAttributionContext(context, attributionTag); 950 } 951 952 return context; 953 } 954 955 /** 956 * Gets the name of the permission required to unexport receivers on pre Tiramisu versions of 957 * Android, and then asserts that the app registering the receiver also has that permission 958 * so it can receiver its own broadcasts. 959 * 960 * @param obj Context to check the permission in. 961 * @return The name of the permission 962 */ obtainAndCheckReceiverPermission(Context obj)963 static String obtainAndCheckReceiverPermission(Context obj) { 964 String permission = obj.getApplicationContext().getPackageName() 965 + DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION_SUFFIX; 966 967 if (PermissionChecker.checkSelfPermission(obj, permission) 968 != PermissionChecker.PERMISSION_GRANTED) { 969 if (Build.VERSION.SDK_INT >= 29) { 970 permission = 971 obj.getOpPackageName() + DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION_SUFFIX; 972 if (PermissionChecker.checkSelfPermission(obj, permission) 973 == PermissionChecker.PERMISSION_GRANTED) { 974 return permission; 975 } 976 } 977 throw new RuntimeException("Permission " + permission + " is required by your " 978 + "application to receive broadcasts, please add it to your manifest"); 979 } 980 return permission; 981 } 982 983 /** Nested class provides lazy initialization only when needed. */ 984 private static final class LegacyServiceMapHolder { 985 static final HashMap<Class<?>, String> SERVICES = new HashMap<>(); 986 987 static { 988 if (Build.VERSION.SDK_INT >= 22) { SERVICES.put(SubscriptionManager.class, TELEPHONY_SUBSCRIPTION_SERVICE)989 SERVICES.put(SubscriptionManager.class, TELEPHONY_SUBSCRIPTION_SERVICE); SERVICES.put(UsageStatsManager.class, USAGE_STATS_SERVICE)990 SERVICES.put(UsageStatsManager.class, USAGE_STATS_SERVICE); 991 } 992 if (Build.VERSION.SDK_INT >= 21) { SERVICES.put(AppWidgetManager.class, APPWIDGET_SERVICE)993 SERVICES.put(AppWidgetManager.class, APPWIDGET_SERVICE); SERVICES.put(BatteryManager.class, BATTERY_SERVICE)994 SERVICES.put(BatteryManager.class, BATTERY_SERVICE); SERVICES.put(CameraManager.class, CAMERA_SERVICE)995 SERVICES.put(CameraManager.class, CAMERA_SERVICE); SERVICES.put(JobScheduler.class, JOB_SCHEDULER_SERVICE)996 SERVICES.put(JobScheduler.class, JOB_SCHEDULER_SERVICE); SERVICES.put(LauncherApps.class, LAUNCHER_APPS_SERVICE)997 SERVICES.put(LauncherApps.class, LAUNCHER_APPS_SERVICE); SERVICES.put(MediaProjectionManager.class, MEDIA_PROJECTION_SERVICE)998 SERVICES.put(MediaProjectionManager.class, MEDIA_PROJECTION_SERVICE); SERVICES.put(MediaSessionManager.class, MEDIA_SESSION_SERVICE)999 SERVICES.put(MediaSessionManager.class, MEDIA_SESSION_SERVICE); SERVICES.put(RestrictionsManager.class, RESTRICTIONS_SERVICE)1000 SERVICES.put(RestrictionsManager.class, RESTRICTIONS_SERVICE); SERVICES.put(TelecomManager.class, TELECOM_SERVICE)1001 SERVICES.put(TelecomManager.class, TELECOM_SERVICE); SERVICES.put(TvInputManager.class, TV_INPUT_SERVICE)1002 SERVICES.put(TvInputManager.class, TV_INPUT_SERVICE); 1003 } 1004 SERVICES.put(AppOpsManager.class, APP_OPS_SERVICE)1005 SERVICES.put(AppOpsManager.class, APP_OPS_SERVICE); SERVICES.put(CaptioningManager.class, CAPTIONING_SERVICE)1006 SERVICES.put(CaptioningManager.class, CAPTIONING_SERVICE); SERVICES.put(ConsumerIrManager.class, CONSUMER_IR_SERVICE)1007 SERVICES.put(ConsumerIrManager.class, CONSUMER_IR_SERVICE); SERVICES.put(PrintManager.class, PRINT_SERVICE)1008 SERVICES.put(PrintManager.class, PRINT_SERVICE); SERVICES.put(BluetoothManager.class, BLUETOOTH_SERVICE)1009 SERVICES.put(BluetoothManager.class, BLUETOOTH_SERVICE); SERVICES.put(DisplayManager.class, DISPLAY_SERVICE)1010 SERVICES.put(DisplayManager.class, DISPLAY_SERVICE); SERVICES.put(UserManager.class, USER_SERVICE)1011 SERVICES.put(UserManager.class, USER_SERVICE); 1012 SERVICES.put(InputManager.class, INPUT_SERVICE)1013 SERVICES.put(InputManager.class, INPUT_SERVICE); SERVICES.put(MediaRouter.class, MEDIA_ROUTER_SERVICE)1014 SERVICES.put(MediaRouter.class, MEDIA_ROUTER_SERVICE); SERVICES.put(NsdManager.class, NSD_SERVICE)1015 SERVICES.put(NsdManager.class, NSD_SERVICE); SERVICES.put(AccessibilityManager.class, ACCESSIBILITY_SERVICE)1016 SERVICES.put(AccessibilityManager.class, ACCESSIBILITY_SERVICE); SERVICES.put(AccountManager.class, ACCOUNT_SERVICE)1017 SERVICES.put(AccountManager.class, ACCOUNT_SERVICE); SERVICES.put(ActivityManager.class, ACTIVITY_SERVICE)1018 SERVICES.put(ActivityManager.class, ACTIVITY_SERVICE); SERVICES.put(AlarmManager.class, ALARM_SERVICE)1019 SERVICES.put(AlarmManager.class, ALARM_SERVICE); SERVICES.put(AudioManager.class, AUDIO_SERVICE)1020 SERVICES.put(AudioManager.class, AUDIO_SERVICE); SERVICES.put(ClipboardManager.class, CLIPBOARD_SERVICE)1021 SERVICES.put(ClipboardManager.class, CLIPBOARD_SERVICE); SERVICES.put(ConnectivityManager.class, CONNECTIVITY_SERVICE)1022 SERVICES.put(ConnectivityManager.class, CONNECTIVITY_SERVICE); SERVICES.put(DevicePolicyManager.class, DEVICE_POLICY_SERVICE)1023 SERVICES.put(DevicePolicyManager.class, DEVICE_POLICY_SERVICE); SERVICES.put(DownloadManager.class, DOWNLOAD_SERVICE)1024 SERVICES.put(DownloadManager.class, DOWNLOAD_SERVICE); SERVICES.put(DropBoxManager.class, DROPBOX_SERVICE)1025 SERVICES.put(DropBoxManager.class, DROPBOX_SERVICE); SERVICES.put(InputMethodManager.class, INPUT_METHOD_SERVICE)1026 SERVICES.put(InputMethodManager.class, INPUT_METHOD_SERVICE); SERVICES.put(KeyguardManager.class, KEYGUARD_SERVICE)1027 SERVICES.put(KeyguardManager.class, KEYGUARD_SERVICE); SERVICES.put(LayoutInflater.class, LAYOUT_INFLATER_SERVICE)1028 SERVICES.put(LayoutInflater.class, LAYOUT_INFLATER_SERVICE); SERVICES.put(LocationManager.class, LOCATION_SERVICE)1029 SERVICES.put(LocationManager.class, LOCATION_SERVICE); SERVICES.put(NfcManager.class, NFC_SERVICE)1030 SERVICES.put(NfcManager.class, NFC_SERVICE); SERVICES.put(NotificationManager.class, NOTIFICATION_SERVICE)1031 SERVICES.put(NotificationManager.class, NOTIFICATION_SERVICE); SERVICES.put(PowerManager.class, POWER_SERVICE)1032 SERVICES.put(PowerManager.class, POWER_SERVICE); SERVICES.put(SearchManager.class, SEARCH_SERVICE)1033 SERVICES.put(SearchManager.class, SEARCH_SERVICE); SERVICES.put(SensorManager.class, SENSOR_SERVICE)1034 SERVICES.put(SensorManager.class, SENSOR_SERVICE); SERVICES.put(StorageManager.class, STORAGE_SERVICE)1035 SERVICES.put(StorageManager.class, STORAGE_SERVICE); SERVICES.put(TelephonyManager.class, TELEPHONY_SERVICE)1036 SERVICES.put(TelephonyManager.class, TELEPHONY_SERVICE); SERVICES.put(TextServicesManager.class, TEXT_SERVICES_MANAGER_SERVICE)1037 SERVICES.put(TextServicesManager.class, TEXT_SERVICES_MANAGER_SERVICE); SERVICES.put(UiModeManager.class, UI_MODE_SERVICE)1038 SERVICES.put(UiModeManager.class, UI_MODE_SERVICE); SERVICES.put(UsbManager.class, USB_SERVICE)1039 SERVICES.put(UsbManager.class, USB_SERVICE); SERVICES.put(Vibrator.class, VIBRATOR_SERVICE)1040 SERVICES.put(Vibrator.class, VIBRATOR_SERVICE); SERVICES.put(WallpaperManager.class, WALLPAPER_SERVICE)1041 SERVICES.put(WallpaperManager.class, WALLPAPER_SERVICE); SERVICES.put(WifiP2pManager.class, WIFI_P2P_SERVICE)1042 SERVICES.put(WifiP2pManager.class, WIFI_P2P_SERVICE); SERVICES.put(WifiManager.class, WIFI_SERVICE)1043 SERVICES.put(WifiManager.class, WIFI_SERVICE); SERVICES.put(WindowManager.class, WINDOW_SERVICE)1044 SERVICES.put(WindowManager.class, WINDOW_SERVICE); 1045 } 1046 } 1047 1048 @RequiresApi(21) 1049 static class Api21Impl { Api21Impl()1050 private Api21Impl() { 1051 // This class is not instantiable. 1052 } 1053 getDrawable(Context obj, int id)1054 static Drawable getDrawable(Context obj, int id) { 1055 return obj.getDrawable(id); 1056 } 1057 getNoBackupFilesDir(Context obj)1058 static File getNoBackupFilesDir(Context obj) { 1059 return obj.getNoBackupFilesDir(); 1060 } 1061 getCodeCacheDir(Context obj)1062 static File getCodeCacheDir(Context obj) { 1063 return obj.getCodeCacheDir(); 1064 } 1065 } 1066 1067 @RequiresApi(23) 1068 static class Api23Impl { Api23Impl()1069 private Api23Impl() { 1070 // This class is not instantiable. 1071 } 1072 getColor(Context obj, int id)1073 static int getColor(Context obj, int id) { 1074 return obj.getColor(id); 1075 } 1076 getSystemService(Context obj, Class<T> serviceClass)1077 static <T> T getSystemService(Context obj, Class<T> serviceClass) { 1078 return obj.getSystemService(serviceClass); 1079 } 1080 getSystemServiceName(Context obj, Class<?> serviceClass)1081 static String getSystemServiceName(Context obj, Class<?> serviceClass) { 1082 return obj.getSystemServiceName(serviceClass); 1083 } 1084 } 1085 1086 @RequiresApi(24) 1087 static class Api24Impl { Api24Impl()1088 private Api24Impl() { 1089 // This class is not instantiable. 1090 } 1091 getDataDir(Context obj)1092 static File getDataDir(Context obj) { 1093 return obj.getDataDir(); 1094 } 1095 createDeviceProtectedStorageContext(Context obj)1096 static Context createDeviceProtectedStorageContext(Context obj) { 1097 return obj.createDeviceProtectedStorageContext(); 1098 } 1099 isDeviceProtectedStorage(Context obj)1100 static boolean isDeviceProtectedStorage(Context obj) { 1101 return obj.isDeviceProtectedStorage(); 1102 } 1103 } 1104 1105 @RequiresApi(26) 1106 static class Api26Impl { Api26Impl()1107 private Api26Impl() { 1108 // This class is not instantiable. 1109 } 1110 registerReceiver(Context obj, @Nullable BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags)1111 static Intent registerReceiver(Context obj, @Nullable BroadcastReceiver receiver, 1112 IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { 1113 if ((flags & RECEIVER_NOT_EXPORTED) != 0 && broadcastPermission == null) { 1114 String permission = obtainAndCheckReceiverPermission(obj); 1115 // receivers that are not exported should also not be visible to instant apps 1116 return obj.registerReceiver(receiver, filter, permission, scheduler); 1117 } 1118 flags &= Context.RECEIVER_VISIBLE_TO_INSTANT_APPS; 1119 return obj.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags); 1120 } 1121 1122 @SuppressWarnings("UnusedReturnValue") startForegroundService(Context obj, Intent service)1123 static ComponentName startForegroundService(Context obj, Intent service) { 1124 return obj.startForegroundService(service); 1125 } 1126 } 1127 1128 @RequiresApi(28) 1129 static class Api28Impl { Api28Impl()1130 private Api28Impl() { 1131 // This class is not instantiable. 1132 } 1133 getMainExecutor(Context obj)1134 static Executor getMainExecutor(Context obj) { 1135 return obj.getMainExecutor(); 1136 } 1137 } 1138 1139 @RequiresApi(30) 1140 static class Api30Impl { Api30Impl()1141 private Api30Impl() { 1142 // This class is not instantiable. 1143 } 1144 getAttributionTag(Context obj)1145 static String getAttributionTag(Context obj) { 1146 return obj.getAttributionTag(); 1147 } 1148 getDisplayOrDefault(Context obj)1149 static Display getDisplayOrDefault(Context obj) { 1150 try { 1151 return obj.getDisplay(); 1152 } catch (UnsupportedOperationException e) { 1153 // Provide a fallback display if the context is not associated with any display. 1154 Log.w(TAG, "The context:" + obj + " is not associated with any display. Return a " 1155 + "fallback display instead."); 1156 return obj.getSystemService(DisplayManager.class) 1157 .getDisplay(Display.DEFAULT_DISPLAY); 1158 } 1159 } 1160 createAttributionContext(@onNull Context context, @Nullable String attributionTag)1161 static @NonNull Context createAttributionContext(@NonNull Context context, 1162 @Nullable String attributionTag) { 1163 return context.createAttributionContext(attributionTag); 1164 } 1165 } 1166 1167 @RequiresApi(33) 1168 static class Api33Impl { Api33Impl()1169 private Api33Impl() { 1170 // This class is not instantiable 1171 } 1172 registerReceiver(Context obj, @Nullable BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags)1173 static Intent registerReceiver(Context obj, @Nullable BroadcastReceiver receiver, 1174 IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { 1175 return obj.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags); 1176 } 1177 } 1178 } 1179