1 /* 2 * Copyright (C) 2010 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.admin; 18 19 import static android.app.admin.DevicePolicyManager.OperationSafetyReason; 20 21 import android.accounts.AccountManager; 22 import android.annotation.BroadcastBehavior; 23 import android.annotation.IntDef; 24 import android.annotation.IntRange; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.SdkConstant; 28 import android.annotation.SdkConstant.SdkConstantType; 29 import android.app.Service; 30 import android.content.BroadcastReceiver; 31 import android.content.ComponentName; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.net.Uri; 35 import android.os.Bundle; 36 import android.os.PersistableBundle; 37 import android.os.Process; 38 import android.os.UserHandle; 39 import android.security.KeyChain; 40 import android.util.Log; 41 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 45 /** 46 * Base class for implementing a device administration component. This 47 * class provides a convenience for interpreting the raw intent actions 48 * that are sent by the system. 49 * 50 * <p>The callback methods, like the base 51 * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()} 52 * method, happen on the main thread of the process. Thus long running 53 * operations must be done on another thread. Note that because a receiver 54 * is done once returning from its receive function, such long-running operations 55 * should probably be done in a {@link Service}. 56 * 57 * <p>When publishing your DeviceAdmin subclass as a receiver, it must 58 * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the 59 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission. A typical 60 * manifest entry would look like:</p> 61 * 62 * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration} 63 * 64 * <p>The meta-data referenced here provides addition information specific 65 * to the device administrator, as parsed by the {@link DeviceAdminInfo} class. 66 * A typical file would be:</p> 67 * 68 * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data} 69 * 70 * <div class="special reference"> 71 * <h3>Developer Guides</h3> 72 * <p>For more information about device administration, read the 73 * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a> 74 * developer guide.</p> 75 * </div> 76 */ 77 public class DeviceAdminReceiver extends BroadcastReceiver { 78 private static final String TAG = "DevicePolicy"; 79 private static final boolean LOCAL_LOGV = false; 80 81 /** 82 * This is the primary action that a device administrator must implement to be 83 * allowed to manage a device. This will be set to the receiver 84 * when the user enables it for administration. You will generally 85 * handle this in {@link DeviceAdminReceiver#onEnabled(Context, Intent)}. To be 86 * supported, the receiver must also require the 87 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so 88 * that other applications can not abuse it. 89 */ 90 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 91 @BroadcastBehavior(explicitOnly = true) 92 public static final String ACTION_DEVICE_ADMIN_ENABLED 93 = "android.app.action.DEVICE_ADMIN_ENABLED"; 94 95 /** 96 * Action sent to a device administrator when the user has requested to 97 * disable it, but before this has actually been done. This gives you 98 * a chance to supply a message to the user about the impact of 99 * disabling your admin, by setting the extra field 100 * {@link #EXTRA_DISABLE_WARNING} in the result Intent. If not set, 101 * no warning will be displayed. If set, the given text will be shown 102 * to the user before they disable your admin. 103 */ 104 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 105 @BroadcastBehavior(explicitOnly = true) 106 public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED 107 = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED"; 108 109 /** 110 * A CharSequence that can be shown to the user informing them of the 111 * impact of disabling your admin. 112 * 113 * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED 114 */ 115 public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING"; 116 117 /** 118 * Action sent to a device administrator when the user has disabled 119 * it. Upon return, the application no longer has access to the 120 * protected device policy manager APIs. You will generally 121 * handle this in {@link DeviceAdminReceiver#onDisabled(Context, Intent)}. Note 122 * that this action will be 123 * sent the receiver regardless of whether it is explicitly listed in 124 * its intent filter. 125 */ 126 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 127 @BroadcastBehavior(explicitOnly = true) 128 public static final String ACTION_DEVICE_ADMIN_DISABLED 129 = "android.app.action.DEVICE_ADMIN_DISABLED"; 130 131 /** 132 * Action sent to a device administrator when the user has changed the password of their device 133 * or profile challenge. You can at this point check the characteristics 134 * of the new password with {@link DevicePolicyManager#isActivePasswordSufficient() 135 * DevicePolicyManager.isActivePasswordSufficient()}. 136 * You will generally 137 * handle this in {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent, UserHandle)}. 138 * 139 * <p>The calling device admin must have requested 140 * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive 141 * this broadcast. 142 */ 143 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 144 @BroadcastBehavior(explicitOnly = true) 145 public static final String ACTION_PASSWORD_CHANGED 146 = "android.app.action.ACTION_PASSWORD_CHANGED"; 147 148 /** 149 * Action sent to a device administrator when the user has entered an incorrect device 150 * or profile challenge password. You can at this point check the 151 * number of failed password attempts there have been with 152 * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts 153 * DevicePolicyManager.getCurrentFailedPasswordAttempts()}. You will generally 154 * handle this in {@link DeviceAdminReceiver#onPasswordFailed(Context, Intent, UserHandle)}. 155 * 156 * <p>The calling device admin must have requested 157 * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive 158 * this broadcast. 159 */ 160 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 161 @BroadcastBehavior(explicitOnly = true) 162 public static final String ACTION_PASSWORD_FAILED 163 = "android.app.action.ACTION_PASSWORD_FAILED"; 164 165 /** 166 * Action sent to a device administrator when the user has successfully entered their device 167 * or profile challenge password, after failing one or more times. You will generally 168 * handle this in {@link DeviceAdminReceiver#onPasswordSucceeded(Context, Intent, UserHandle)}. 169 * 170 * <p>The calling device admin must have requested 171 * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive 172 * this broadcast. 173 */ 174 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 175 @BroadcastBehavior(explicitOnly = true) 176 public static final String ACTION_PASSWORD_SUCCEEDED 177 = "android.app.action.ACTION_PASSWORD_SUCCEEDED"; 178 179 /** 180 * Action periodically sent to a device administrator when the device or profile challenge 181 * password is expiring. You will generally 182 * handle this in {@link DeviceAdminReceiver#onPasswordExpiring(Context, Intent, UserHandle)}. 183 * 184 * <p>The calling device admin must have requested 185 * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to receive 186 * this broadcast. 187 */ 188 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 189 @BroadcastBehavior(explicitOnly = true) 190 public static final String ACTION_PASSWORD_EXPIRING 191 = "android.app.action.ACTION_PASSWORD_EXPIRING"; 192 193 /** 194 * Action sent to a device administrator to notify that the device is entering 195 * lock task mode. The extra {@link #EXTRA_LOCK_TASK_PACKAGE} 196 * will describe the package using lock task mode. 197 * 198 * <p>The calling device admin must be the device owner or profile 199 * owner to receive this broadcast. 200 * 201 * @see DevicePolicyManager#isLockTaskPermitted(String) 202 */ 203 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 204 @BroadcastBehavior(explicitOnly = true) 205 public static final String ACTION_LOCK_TASK_ENTERING 206 = "android.app.action.LOCK_TASK_ENTERING"; 207 208 /** 209 * Action sent to a device administrator to notify that the device is exiting 210 * lock task mode. 211 * 212 * <p>The calling device admin must be the device owner or profile 213 * owner to receive this broadcast. 214 * 215 * @see DevicePolicyManager#isLockTaskPermitted(String) 216 */ 217 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 218 @BroadcastBehavior(explicitOnly = true) 219 public static final String ACTION_LOCK_TASK_EXITING 220 = "android.app.action.LOCK_TASK_EXITING"; 221 222 /** 223 * A string containing the name of the package entering lock task mode. 224 * 225 * @see #ACTION_LOCK_TASK_ENTERING 226 */ 227 public static final String EXTRA_LOCK_TASK_PACKAGE = 228 "android.app.extra.LOCK_TASK_PACKAGE"; 229 230 /** 231 * Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile 232 * or managed device has completed successfully. 233 * 234 * <p>The broadcast is limited to the profile that will be managed by the application that 235 * requested provisioning. In the device owner case the profile is the primary user. 236 * The broadcast will also be limited to the {@link DeviceAdminReceiver} component 237 * specified in the original intent or NFC bump that started the provisioning process 238 * (see {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE 239 * DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE}). 240 * 241 * <p>A device admin application which listens to this intent can find out if the device was 242 * provisioned for the device owner or profile owner case by calling respectively 243 * {@link android.app.admin.DevicePolicyManager#isDeviceOwnerApp} and 244 * {@link android.app.admin.DevicePolicyManager#isProfileOwnerApp}. You will generally handle 245 * this in {@link DeviceAdminReceiver#onProfileProvisioningComplete}. 246 * 247 * <p>The intent for this action may include the following extras: 248 * <ul> 249 * <li>{@link DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE} 250 * 251 * @see DevicePolicyManager#ACTION_PROVISIONING_SUCCESSFUL 252 */ 253 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 254 @BroadcastBehavior(explicitOnly = true) 255 public static final String ACTION_PROFILE_PROVISIONING_COMPLETE = 256 "android.app.action.PROFILE_PROVISIONING_COMPLETE"; 257 258 /** 259 * Action sent to a device administrator to notify that the device user 260 * has declined sharing a bugreport. 261 * 262 * <p>The calling device admin must be the device owner to receive this broadcast. 263 * @see DevicePolicyManager#requestBugreport 264 * @hide 265 */ 266 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 267 @BroadcastBehavior(explicitOnly = true) 268 public static final String ACTION_BUGREPORT_SHARING_DECLINED = 269 "android.app.action.BUGREPORT_SHARING_DECLINED"; 270 271 /** 272 * Action sent to a device administrator to notify that the collection of a bugreport 273 * has failed. 274 * 275 * <p>The calling device admin must be the device owner to receive this broadcast. 276 * @see DevicePolicyManager#requestBugreport 277 * @hide 278 */ 279 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 280 @BroadcastBehavior(explicitOnly = true) 281 public static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED"; 282 283 /** 284 * Action sent to a device administrator to share the bugreport. 285 * 286 * <p>The calling device admin must be the device owner to receive this broadcast. 287 * @see DevicePolicyManager#requestBugreport 288 * @hide 289 */ 290 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 291 @BroadcastBehavior(explicitOnly = true) 292 public static final String ACTION_BUGREPORT_SHARE = 293 "android.app.action.BUGREPORT_SHARE"; 294 295 /** 296 * Broadcast action: notify that a new batch of security logs is ready to be collected. 297 */ 298 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 299 @BroadcastBehavior(explicitOnly = true) 300 public static final String ACTION_SECURITY_LOGS_AVAILABLE 301 = "android.app.action.SECURITY_LOGS_AVAILABLE"; 302 303 /** 304 * Broadcast action: notify that a new batch of network logs is ready to be collected. 305 * @see DeviceAdminReceiver#onNetworkLogsAvailable 306 * @see DelegatedAdminReceiver#onNetworkLogsAvailable 307 */ 308 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 309 @BroadcastBehavior(explicitOnly = true) 310 public static final String ACTION_NETWORK_LOGS_AVAILABLE 311 = "android.app.action.NETWORK_LOGS_AVAILABLE"; 312 313 /** 314 * A {@code long} containing a token of the current batch of network logs, that has to be used 315 * to retrieve the batch of logs by the device owner. 316 * 317 * @see #ACTION_NETWORK_LOGS_AVAILABLE 318 * @see DevicePolicyManager#retrieveNetworkLogs 319 * @hide 320 */ 321 public static final String EXTRA_NETWORK_LOGS_TOKEN = 322 "android.app.extra.EXTRA_NETWORK_LOGS_TOKEN"; 323 324 /** 325 * An {@code int} count representing a total count of network logs inside the current batch of 326 * network logs. 327 * 328 * @see #ACTION_NETWORK_LOGS_AVAILABLE 329 * @hide 330 */ 331 public static final String EXTRA_NETWORK_LOGS_COUNT = 332 "android.app.extra.EXTRA_NETWORK_LOGS_COUNT"; 333 334 /** 335 * Broadcast action: notify the device owner that a user or profile has been added. 336 * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of 337 * the new user. 338 * @hide 339 */ 340 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 341 @BroadcastBehavior(explicitOnly = true) 342 public static final String ACTION_USER_ADDED = "android.app.action.USER_ADDED"; 343 344 /** 345 * Broadcast action: notify the device owner that a user or profile has been removed. 346 * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of 347 * the user. 348 * @hide 349 */ 350 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 351 @BroadcastBehavior(explicitOnly = true) 352 public static final String ACTION_USER_REMOVED = "android.app.action.USER_REMOVED"; 353 354 /** 355 * Broadcast action: notify the device owner that a user or profile has been started. 356 * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of 357 * the user. 358 * @hide 359 */ 360 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 361 @BroadcastBehavior(explicitOnly = true) 362 public static final String ACTION_USER_STARTED = "android.app.action.USER_STARTED"; 363 364 /** 365 * Broadcast action: notify the device owner that a user or profile has been stopped. 366 * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of 367 * the user. 368 * @hide 369 */ 370 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 371 @BroadcastBehavior(explicitOnly = true) 372 public static final String ACTION_USER_STOPPED = "android.app.action.USER_STOPPED"; 373 374 /** 375 * Broadcast action: notify the device owner that a user or profile has been switched to. 376 * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of 377 * the user. 378 * @hide 379 */ 380 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 381 @BroadcastBehavior(explicitOnly = true) 382 public static final String ACTION_USER_SWITCHED = "android.app.action.USER_SWITCHED"; 383 384 /** 385 * A string containing the SHA-256 hash of the bugreport file. 386 * 387 * @see #ACTION_BUGREPORT_SHARE 388 * @hide 389 */ 390 public static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH"; 391 392 /** 393 * An {@code int} failure code representing the reason of the bugreport failure. One of 394 * {@link #BUGREPORT_FAILURE_FAILED_COMPLETING} 395 * or {@link #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE} 396 * 397 * @see #ACTION_BUGREPORT_FAILED 398 * @hide 399 */ 400 public static final String EXTRA_BUGREPORT_FAILURE_REASON = 401 "android.app.extra.BUGREPORT_FAILURE_REASON"; 402 403 /** 404 * An interface representing reason of bugreport failure. 405 * 406 * @see #EXTRA_BUGREPORT_FAILURE_REASON 407 * @hide 408 */ 409 @Retention(RetentionPolicy.SOURCE) 410 @IntDef(prefix = { "BUGREPORT_FAILURE_" }, value = { 411 BUGREPORT_FAILURE_FAILED_COMPLETING, 412 BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE 413 }) 414 public @interface BugreportFailureCode {} 415 416 /** 417 * Bugreport completion process failed. 418 * 419 * <p>If this error code is received, the requesting of bugreport can be retried. 420 * @see DevicePolicyManager#requestBugreport 421 */ 422 public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0; 423 424 /** 425 * Bugreport has been created, but is no longer available for collection. 426 * 427 * <p>This error likely occurs because the user of the device hasn't consented to share 428 * the bugreport for a long period after its creation. 429 * 430 * <p>If this error code is received, the requesting of bugreport can be retried. 431 * @see DevicePolicyManager#requestBugreport 432 */ 433 public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1; 434 435 /** 436 * Broadcast action: notify that some app is attempting to choose a KeyChain key. 437 * @see DeviceAdminReceiver#onChoosePrivateKeyAlias 438 * @see DelegatedAdminReceiver#onChoosePrivateKeyAlias 439 */ 440 public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS = 441 "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS"; 442 443 /** @hide */ 444 public static final String EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID = 445 "android.app.extra.CHOOSE_PRIVATE_KEY_SENDER_UID"; 446 447 /** @hide */ 448 public static final String EXTRA_CHOOSE_PRIVATE_KEY_URI = 449 "android.app.extra.CHOOSE_PRIVATE_KEY_URI"; 450 451 /** @hide */ 452 public static final String EXTRA_CHOOSE_PRIVATE_KEY_ALIAS = 453 "android.app.extra.CHOOSE_PRIVATE_KEY_ALIAS"; 454 455 /** @hide */ 456 public static final String EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE = 457 "android.app.extra.CHOOSE_PRIVATE_KEY_RESPONSE"; 458 459 /** 460 * Broadcast action: notify device owner that there is a pending system update. 461 * @hide 462 */ 463 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 464 @BroadcastBehavior(explicitOnly = true) 465 public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE = 466 "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE"; 467 468 /** 469 * A long type extra for {@link #onSystemUpdatePending} recording the system time as given by 470 * {@link System#currentTimeMillis()} when the current pending system update is first available. 471 * @hide 472 */ 473 public static final String EXTRA_SYSTEM_UPDATE_RECEIVED_TIME = 474 "android.app.extra.SYSTEM_UPDATE_RECEIVED_TIME"; 475 476 /** 477 * Name under which a DevicePolicy component publishes information 478 * about itself. This meta-data must reference an XML resource containing 479 * a device-admin tag. 480 */ 481 // TO DO: describe syntax. 482 public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin"; 483 484 /** 485 * Broadcast action: notify the newly transferred administrator that the transfer 486 * from the original administrator was successful. 487 * 488 * @hide 489 */ 490 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 491 public static final String ACTION_TRANSFER_OWNERSHIP_COMPLETE = 492 "android.app.action.TRANSFER_OWNERSHIP_COMPLETE"; 493 494 /** 495 * Broadcast action: notify the device owner that the ownership of one of its affiliated 496 * profiles is transferred. 497 * 498 * @hide 499 */ 500 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 501 public static final String ACTION_AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE = 502 "android.app.action.AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE"; 503 504 /** 505 * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that 506 * allows a mobile device management application to pass data to the management application 507 * instance after owner transfer. 508 * 509 * <p>If the transfer is successful, the new owner receives the data in 510 * {@link DeviceAdminReceiver#onTransferOwnershipComplete(Context, PersistableBundle)}. 511 * The bundle is not changed during the ownership transfer. 512 * 513 * @see DevicePolicyManager#transferOwnership(ComponentName, ComponentName, PersistableBundle) 514 */ 515 public static final String EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE = 516 "android.app.extra.TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE"; 517 518 /** 519 * Broadcast action: notify the admin that the state of operations that can be unsafe because 520 * of a given reason (specified by the {@link #EXTRA_OPERATION_SAFETY_REASON} {@code int} extra) 521 * has changed (the new value is specified by the {@link #EXTRA_OPERATION_SAFETY_STATE} 522 * {@code boolean} extra). 523 * 524 * @hide 525 */ 526 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 527 public static final String ACTION_OPERATION_SAFETY_STATE_CHANGED = 528 "android.app.action.OPERATION_SAFETY_STATE_CHANGED"; 529 530 /** 531 * Broadcast action: notify the profile owner on an organization-owned device that it needs to 532 * acknowledge device compliance. 533 * 534 * @hide 535 */ 536 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 537 public static final String ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED = 538 "android.app.action.COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED"; 539 540 /** 541 * An {@code int} extra specifying an {@link OperationSafetyReason}. 542 * 543 * @hide 544 */ 545 public static final String EXTRA_OPERATION_SAFETY_REASON = 546 "android.app.extra.OPERATION_SAFETY_REASON"; 547 548 /** 549 * An {@code boolean} extra specifying whether an operation will fail due to a 550 * {@link OperationSafetyReason}. {@code true} means operations that rely on that reason are 551 * safe, while {@code false} means they're unsafe. 552 * 553 * @hide 554 */ 555 public static final String EXTRA_OPERATION_SAFETY_STATE = 556 "android.app.extra.OPERATION_SAFETY_STATE"; 557 558 private DevicePolicyManager mManager; 559 private ComponentName mWho; 560 561 /** 562 * Retrieve the DevicePolicyManager interface for this administrator to work 563 * with the system. 564 */ getManager(@onNull Context context)565 public @NonNull DevicePolicyManager getManager(@NonNull Context context) { 566 if (mManager != null) { 567 return mManager; 568 } 569 mManager = (DevicePolicyManager)context.getSystemService( 570 Context.DEVICE_POLICY_SERVICE); 571 return mManager; 572 } 573 574 /** 575 * Retrieve the ComponentName describing who this device administrator is, for 576 * use in {@link DevicePolicyManager} APIs that require the administrator to 577 * identify itself. 578 */ getWho(@onNull Context context)579 public @NonNull ComponentName getWho(@NonNull Context context) { 580 if (mWho != null) { 581 return mWho; 582 } 583 mWho = new ComponentName(context, getClass()); 584 return mWho; 585 } 586 587 /** 588 * Called after the administrator is first enabled, as a result of 589 * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}. At this point you 590 * can use {@link DevicePolicyManager} to set your desired policies. 591 * 592 * <p> If the admin is activated by a device owner, then the intent 593 * may contain private extras that are relevant to user setup. 594 * {@see DevicePolicyManager#createAndManageUser(ComponentName, String, ComponentName, 595 * PersistableBundle, int)} 596 * 597 * @param context The running context as per {@link #onReceive}. 598 * @param intent The received intent as per {@link #onReceive}. 599 */ onEnabled(@onNull Context context, @NonNull Intent intent)600 public void onEnabled(@NonNull Context context, @NonNull Intent intent) { 601 if (LOCAL_LOGV) { 602 Log.v(TAG, getClass().getName() + ".onEnabled() on user " + context.getUserId()); 603 } 604 } 605 606 /** 607 * Called when the user has asked to disable the administrator, as a result of 608 * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you 609 * a chance to present a warning message to them. The message is returned 610 * as the result; if null is returned (the default implementation), no 611 * message will be displayed. 612 * @param context The running context as per {@link #onReceive}. 613 * @param intent The received intent as per {@link #onReceive}. 614 * @return Return the warning message to display to the user before 615 * being disabled; if null is returned, no message is displayed. 616 */ onDisableRequested(@onNull Context context, @NonNull Intent intent)617 public @Nullable CharSequence onDisableRequested(@NonNull Context context, 618 @NonNull Intent intent) { 619 if (LOCAL_LOGV) { 620 Log.v(TAG, getClass().getName() + ".onDisableRequested() on user " 621 + context.getUserId()); 622 } 623 return null; 624 } 625 626 /** 627 * Called prior to the administrator being disabled, as a result of 628 * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}. Upon return, you 629 * can no longer use the protected parts of the {@link DevicePolicyManager} 630 * API. 631 * @param context The running context as per {@link #onReceive}. 632 * @param intent The received intent as per {@link #onReceive}. 633 */ onDisabled(@onNull Context context, @NonNull Intent intent)634 public void onDisabled(@NonNull Context context, @NonNull Intent intent) { 635 if (LOCAL_LOGV) { 636 Log.v(TAG, getClass().getName() + ".onDisabled() on user " + context.getUserId()); 637 } 638 } 639 640 /** 641 * Called after the user has changed their device or profile challenge password, as a result of 642 * receiving {@link #ACTION_PASSWORD_CHANGED}. At this point you 643 * can use {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} 644 * to retrieve the active password characteristics. 645 * @param context The running context as per {@link #onReceive}. 646 * @param intent The received intent as per {@link #onReceive}. 647 * 648 * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use 649 * {@link #onPasswordChanged(Context, Intent, UserHandle)} instead. 650 */ 651 @Deprecated onPasswordChanged(@onNull Context context, @NonNull Intent intent)652 public void onPasswordChanged(@NonNull Context context, @NonNull Intent intent) { 653 } 654 655 /** 656 * Called after the user has changed their device or profile challenge password, as a result of 657 * receiving {@link #ACTION_PASSWORD_CHANGED}. At this point you 658 * can use {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} 659 * to retrieve the active password characteristics. 660 * @param context The running context as per {@link #onReceive}. 661 * @param intent The received intent as per {@link #onReceive}. 662 * @param user The user or profile for whom the password changed. To see whether this 663 * user is the current profile or a parent user, check for equality with 664 * {@link Process#myUserHandle}. 665 */ onPasswordChanged(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle user)666 public void onPasswordChanged(@NonNull Context context, @NonNull Intent intent, 667 @NonNull UserHandle user) { 668 onPasswordChanged(context, intent); 669 } 670 671 /** 672 * Called after the user has failed at entering their device or profile challenge password, 673 * as a result of receiving {@link #ACTION_PASSWORD_FAILED}. At this point you can use 674 * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()} to retrieve the number of 675 * failed password attempts. 676 * @param context The running context as per {@link #onReceive}. 677 * @param intent The received intent as per {@link #onReceive}. 678 * 679 * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use 680 * {@link #onPasswordFailed(Context, Intent, UserHandle)} instead. 681 */ 682 @Deprecated onPasswordFailed(@onNull Context context, @NonNull Intent intent)683 public void onPasswordFailed(@NonNull Context context, @NonNull Intent intent) { 684 } 685 686 /** 687 * Called after the user has failed at entering their device or profile challenge password, 688 * as a result of receiving {@link #ACTION_PASSWORD_FAILED}. At this point you can use 689 * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()} to retrieve the number of 690 * failed password attempts. 691 * @param context The running context as per {@link #onReceive}. 692 * @param intent The received intent as per {@link #onReceive}. 693 * @param user The user or profile for whom the password check failed. To see whether this 694 * user is the current profile or a parent user, check for equality with 695 * {@link Process#myUserHandle}. 696 */ onPasswordFailed(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle user)697 public void onPasswordFailed(@NonNull Context context, @NonNull Intent intent, 698 @NonNull UserHandle user) { 699 onPasswordFailed(context, intent); 700 } 701 702 /** 703 * Called after the user has succeeded at entering their device or profile challenge password, 704 * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}. This will 705 * only be received the first time they succeed after having previously 706 * failed. 707 * @param context The running context as per {@link #onReceive}. 708 * @param intent The received intent as per {@link #onReceive}. 709 * 710 * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use 711 * {@link #onPasswordSucceeded(Context, Intent, UserHandle)} instead. 712 */ 713 @Deprecated onPasswordSucceeded(@onNull Context context, @NonNull Intent intent)714 public void onPasswordSucceeded(@NonNull Context context, @NonNull Intent intent) { 715 } 716 717 /** 718 * Called after the user has succeeded at entering their device or profile challenge password, 719 * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}. This will 720 * only be received the first time they succeed after having previously 721 * failed. 722 * @param context The running context as per {@link #onReceive}. 723 * @param intent The received intent as per {@link #onReceive}. 724 * @param user The user of profile for whom the password check succeeded. To see whether this 725 * user is the current profile or a parent user, check for equality with 726 * {@link Process#myUserHandle}. 727 */ onPasswordSucceeded(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle user)728 public void onPasswordSucceeded(@NonNull Context context, @NonNull Intent intent, 729 @NonNull UserHandle user) { 730 onPasswordSucceeded(context, intent); 731 } 732 733 /** 734 * Called periodically when the device or profile challenge password is about to expire 735 * or has expired. It will typically be called at these times: on device boot, once per day 736 * before the password expires, and at the time when the password expires. 737 * 738 * <p>If the password is not updated by the user, this method will continue to be called 739 * once per day until the password is changed or the device admin disables password expiration. 740 * 741 * <p>The admin will typically post a notification requesting the user to change their password 742 * in response to this call. The actual password expiration time can be obtained by calling 743 * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) } 744 * 745 * <p>The admin should be sure to take down any notifications it posted in response to this call 746 * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent) }. 747 * 748 * @param context The running context as per {@link #onReceive}. 749 * @param intent The received intent as per {@link #onReceive}. 750 * 751 * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use 752 * {@link #onPasswordExpiring(Context, Intent, UserHandle)} instead. 753 */ 754 @Deprecated onPasswordExpiring(@onNull Context context, @NonNull Intent intent)755 public void onPasswordExpiring(@NonNull Context context, @NonNull Intent intent) { 756 } 757 758 /** 759 * Called periodically when the device or profile challenge password is about to expire 760 * or has expired. It will typically be called at these times: on device boot, once per day 761 * before the password expires, and at the time when the password expires. 762 * 763 * <p>If the password is not updated by the user, this method will continue to be called 764 * once per day until the password is changed or the device admin disables password expiration. 765 * 766 * <p>The admin will typically post a notification requesting the user to change their password 767 * in response to this call. The actual password expiration time can be obtained by calling 768 * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) } 769 * 770 * <p>The admin should be sure to take down any notifications it posted in response to this call 771 * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent, UserHandle) }. 772 * 773 * @param context The running context as per {@link #onReceive}. 774 * @param intent The received intent as per {@link #onReceive}. 775 * @param user The user or profile for whom the password is expiring. To see whether this 776 * user is the current profile or a parent user, check for equality with 777 * {@link Process#myUserHandle}. 778 */ onPasswordExpiring(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle user)779 public void onPasswordExpiring(@NonNull Context context, @NonNull Intent intent, 780 @NonNull UserHandle user) { 781 onPasswordExpiring(context, intent); 782 } 783 784 /** 785 * Called when provisioning of a managed profile or managed device has completed successfully. 786 * 787 * <p> As a prerequisite for the execution of this callback the {@link DeviceAdminReceiver} has 788 * to declare an intent filter for {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}. 789 * Its component must also be specified in the {@link DevicePolicyManager#EXTRA_DEVICE_ADMIN} 790 * of the {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the 791 * managed provisioning. 792 * 793 * <p>When provisioning of a managed profile is complete, the managed profile is hidden until 794 * the profile owner calls {@link DevicePolicyManager#setProfileEnabled(ComponentName admin)}. 795 * Typically a profile owner will enable the profile when it has finished any additional setup 796 * such as adding an account by using the {@link AccountManager} and calling APIs to bring the 797 * profile into the desired state. 798 * 799 * <p> Note that provisioning completes without waiting for any server interactions, so the 800 * profile owner needs to wait for data to be available if required (e.g. Android device IDs or 801 * other data that is set as a result of server interactions). 802 * 803 * <p>From version {@link android.os.Build.VERSION_CODES#O}, when managed provisioning has 804 * completed, along with this callback the activity intent 805 * {@link DevicePolicyManager#ACTION_PROVISIONING_SUCCESSFUL} will also be sent to the same 806 * application. 807 * 808 * <p>The {@code Intent} may include any of the extras specified for 809 * {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}. 810 * 811 * @param context The running context as per {@link #onReceive}. 812 * @param intent The received intent as per {@link #onReceive}. 813 */ onProfileProvisioningComplete(@onNull Context context, @NonNull Intent intent)814 public void onProfileProvisioningComplete(@NonNull Context context, @NonNull Intent intent) { 815 if (LOCAL_LOGV) { 816 Log.v(TAG, getClass().getName() + ".onProfileProvisioningComplete() on user " 817 + context.getUserId()); 818 } 819 } 820 821 /** 822 * Called during provisioning of a managed device to allow the device initializer to perform 823 * user setup steps. 824 * 825 * @param context The running context as per {@link #onReceive}. 826 * @param intent The received intent as per {@link #onReceive}. 827 * @deprecated Do not use 828 */ 829 @Deprecated onReadyForUserInitialization(@onNull Context context, @NonNull Intent intent)830 public void onReadyForUserInitialization(@NonNull Context context, @NonNull Intent intent) { 831 } 832 833 /** 834 * Called when a device is entering lock task mode. 835 * 836 * @param context The running context as per {@link #onReceive}. 837 * @param intent The received intent as per {@link #onReceive}. 838 * @param pkg The authorized package using lock task mode. 839 */ onLockTaskModeEntering(@onNull Context context, @NonNull Intent intent, @NonNull String pkg)840 public void onLockTaskModeEntering(@NonNull Context context, @NonNull Intent intent, 841 @NonNull String pkg) { 842 } 843 844 /** 845 * Called when a device is exiting lock task mode. 846 * 847 * @param context The running context as per {@link #onReceive}. 848 * @param intent The received intent as per {@link #onReceive}. 849 */ onLockTaskModeExiting(@onNull Context context, @NonNull Intent intent)850 public void onLockTaskModeExiting(@NonNull Context context, @NonNull Intent intent) { 851 } 852 853 /** 854 * Allows this receiver to select the alias for a private key and certificate pair for 855 * authentication. If this method returns null, the default {@link android.app.Activity} will be 856 * shown that lets the user pick a private key and certificate pair. 857 * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED}, 858 * the default {@link android.app.Activity} will not be shown and the user will not be allowed 859 * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will 860 * receive {@code null} back. 861 * 862 * @param context The running context as per {@link #onReceive}. 863 * @param intent The received intent as per {@link #onReceive}. 864 * @param uid The uid of the app asking for the private key and certificate pair. 865 * @param uri The URI to authenticate, may be null. 866 * @param alias The alias preselected by the client, or null. 867 * @return The private key alias to return and grant access to. 868 * @see KeyChain#choosePrivateKeyAlias 869 */ onChoosePrivateKeyAlias(@onNull Context context, @NonNull Intent intent, int uid, @Nullable Uri uri, @Nullable String alias)870 public @Nullable String onChoosePrivateKeyAlias(@NonNull Context context, 871 @NonNull Intent intent, int uid, @Nullable Uri uri, @Nullable String alias) { 872 return null; 873 } 874 875 /** 876 * Called when the information about a pending system update is available. 877 * 878 * <p>Allows the receiver to be notified when information about a pending system update is 879 * available from the system update service. The same pending system update can trigger multiple 880 * calls to this method, so it is necessary to examine the incoming parameters for details about 881 * the update. 882 * 883 * <p>This callback is only applicable to device owners and profile owners. 884 * 885 * <p>To get further information about a pending system update (for example, whether or not the 886 * update is a security patch), the device owner or profile owner can call 887 * {@link DevicePolicyManager#getPendingSystemUpdate}. 888 * 889 * @param context The running context as per {@link #onReceive}. 890 * @param intent The received intent as per {@link #onReceive}. 891 * @param receivedTime The time as given by {@link System#currentTimeMillis()} indicating when 892 * the current pending update was first available. -1 if no pending update is available. 893 * @see DevicePolicyManager#getPendingSystemUpdate 894 */ onSystemUpdatePending(@onNull Context context, @NonNull Intent intent, long receivedTime)895 public void onSystemUpdatePending(@NonNull Context context, @NonNull Intent intent, 896 long receivedTime) { 897 } 898 899 /** 900 * Called when sharing a bugreport has been cancelled by the user of the device. 901 * 902 * <p>This callback is only applicable to device owners. 903 * 904 * @param context The running context as per {@link #onReceive}. 905 * @param intent The received intent as per {@link #onReceive}. 906 * @see DevicePolicyManager#requestBugreport 907 */ onBugreportSharingDeclined(@onNull Context context, @NonNull Intent intent)908 public void onBugreportSharingDeclined(@NonNull Context context, @NonNull Intent intent) { 909 } 910 911 /** 912 * Called when the bugreport has been shared with the device administrator app. 913 * 914 * <p>This callback is only applicable to device owners. 915 * 916 * @param context The running context as per {@link #onReceive}. 917 * @param intent The received intent as per {@link #onReceive}. Contains the URI of 918 * the bugreport file (with MIME type "application/vnd.android.bugreport"), that can be accessed 919 * by calling {@link Intent#getData()} 920 * @param bugreportHash SHA-256 hash of the bugreport file. 921 * @see DevicePolicyManager#requestBugreport 922 */ onBugreportShared(@onNull Context context, @NonNull Intent intent, @NonNull String bugreportHash)923 public void onBugreportShared(@NonNull Context context, @NonNull Intent intent, 924 @NonNull String bugreportHash) { 925 } 926 927 /** 928 * Called when the bugreport collection flow has failed. 929 * 930 * <p>This callback is only applicable to device owners. 931 * 932 * @param context The running context as per {@link #onReceive}. 933 * @param intent The received intent as per {@link #onReceive}. 934 * @param failureCode int containing failure code. One of 935 * {@link #BUGREPORT_FAILURE_FAILED_COMPLETING} 936 * or {@link #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE} 937 * @see DevicePolicyManager#requestBugreport 938 */ onBugreportFailed(@onNull Context context, @NonNull Intent intent, @BugreportFailureCode int failureCode)939 public void onBugreportFailed(@NonNull Context context, @NonNull Intent intent, 940 @BugreportFailureCode int failureCode) { 941 } 942 943 /** 944 * Called when a new batch of security logs can be retrieved. 945 * 946 * <p>If a secondary user or profile is created, this callback won't be received until all users 947 * become affiliated again (even if security logging is enabled). 948 * See {@link DevicePolicyManager#setAffiliationIds} 949 * 950 * <p>This callback will be re-triggered if the logs are not retrieved. 951 * 952 * <p>This callback is only applicable to device owners and profile owners of 953 * organization-owned managed profiles. 954 * 955 * <p> 956 * This callback is triggered by a foreground broadcast and the app should ensure that any 957 * long-running work is not executed synchronously inside the callback. 958 * 959 * @param context The running context as per {@link #onReceive}. 960 * @param intent The received intent as per {@link #onReceive}. 961 * @see DevicePolicyManager#retrieveSecurityLogs(ComponentName) 962 */ onSecurityLogsAvailable(@onNull Context context, @NonNull Intent intent)963 public void onSecurityLogsAvailable(@NonNull Context context, @NonNull Intent intent) { 964 } 965 966 /** 967 * Called each time a new batch of network logs can be retrieved. This callback method will only 968 * ever be called when network logging is enabled. The logs can only be retrieved while network 969 * logging is enabled. 970 * 971 * <p>If a secondary user or profile is created, this callback won't be received until all users 972 * become affiliated again (even if network logging is enabled). It will also no longer be 973 * possible to retrieve the network logs batch with the most recent {@code batchToken} provided 974 * by this callback. See {@link DevicePolicyManager#setAffiliationIds}. 975 * 976 * <p>This callback is only applicable to device owners and profile owners. 977 * 978 * <p> 979 * This callback is triggered by a foreground broadcast and the app should ensure that any 980 * long-running work is not executed synchronously inside the callback. 981 * 982 * @param context The running context as per {@link #onReceive}. 983 * @param intent The received intent as per {@link #onReceive}. 984 * @param batchToken The token representing the current batch of network logs. 985 * @param networkLogsCount The total count of events in the current batch of network logs. 986 * @see DevicePolicyManager#retrieveNetworkLogs 987 */ onNetworkLogsAvailable(@onNull Context context, @NonNull Intent intent, long batchToken, @IntRange(from = 1) int networkLogsCount)988 public void onNetworkLogsAvailable(@NonNull Context context, @NonNull Intent intent, 989 long batchToken, @IntRange(from = 1) int networkLogsCount) { 990 } 991 992 /** 993 * Called when a user or profile is created. 994 * 995 * <p>This callback is only applicable to device owners. 996 * 997 * @param context The running context as per {@link #onReceive}. 998 * @param intent The received intent as per {@link #onReceive}. 999 * @param addedUser The {@link UserHandle} of the user that has just been added. 1000 */ onUserAdded(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle addedUser)1001 public void onUserAdded(@NonNull Context context, @NonNull Intent intent, 1002 @NonNull UserHandle addedUser) { 1003 if (LOCAL_LOGV) { 1004 Log.v(TAG, getClass().getName() + ".onUserAdded() on user " + context.getUserId()); 1005 } 1006 } 1007 1008 /** 1009 * Called when a user or profile is removed. 1010 * 1011 * <p>This callback is only applicable to device owners. 1012 * 1013 * @param context The running context as per {@link #onReceive}. 1014 * @param intent The received intent as per {@link #onReceive}. 1015 * @param removedUser The {@link UserHandle} of the user that has just been removed. 1016 */ onUserRemoved(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle removedUser)1017 public void onUserRemoved(@NonNull Context context, @NonNull Intent intent, 1018 @NonNull UserHandle removedUser) { 1019 if (LOCAL_LOGV) { 1020 Log.v(TAG, getClass().getName() + ".onUserRemoved() on user " + context.getUserId()); 1021 } 1022 } 1023 1024 /** 1025 * Called when a user or profile is started. 1026 * 1027 * <p>This callback is only applicable to device owners. 1028 * 1029 * @param context The running context as per {@link #onReceive}. 1030 * @param intent The received intent as per {@link #onReceive}. 1031 * @param startedUser The {@link UserHandle} of the user that has just been started. 1032 */ onUserStarted(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle startedUser)1033 public void onUserStarted(@NonNull Context context, @NonNull Intent intent, 1034 @NonNull UserHandle startedUser) { 1035 if (LOCAL_LOGV) { 1036 Log.v(TAG, getClass().getName() + ".onUserStarted() on user " + context.getUserId()); 1037 } 1038 } 1039 1040 /** 1041 * Called when a user or profile is stopped. 1042 * 1043 * <p>This callback is only applicable to device owners. 1044 * 1045 * @param context The running context as per {@link #onReceive}. 1046 * @param intent The received intent as per {@link #onReceive}. 1047 * @param stoppedUser The {@link UserHandle} of the user that has just been stopped. 1048 */ onUserStopped(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle stoppedUser)1049 public void onUserStopped(@NonNull Context context, @NonNull Intent intent, 1050 @NonNull UserHandle stoppedUser) { 1051 if (LOCAL_LOGV) { 1052 Log.v(TAG, getClass().getName() + ".onUserStopped() on user " + context.getUserId()); 1053 } 1054 } 1055 1056 /** 1057 * Called when a user or profile is switched to. 1058 * 1059 * <p>This callback is only applicable to device owners. 1060 * 1061 * @param context The running context as per {@link #onReceive}. 1062 * @param intent The received intent as per {@link #onReceive}. 1063 * @param switchedUser The {@link UserHandle} of the user that has just been switched to. 1064 */ onUserSwitched(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle switchedUser)1065 public void onUserSwitched(@NonNull Context context, @NonNull Intent intent, 1066 @NonNull UserHandle switchedUser) { 1067 if (LOCAL_LOGV) { 1068 Log.v(TAG, getClass().getName() + ".onUserSwitched() on user " + context.getUserId()); 1069 } 1070 } 1071 1072 /** 1073 * Called on the newly assigned owner (either device owner or profile owner) when the ownership 1074 * transfer has completed successfully. 1075 * 1076 * <p> The {@code bundle} parameter allows the original owner to pass data 1077 * to the new one. 1078 * 1079 * @param context the running context as per {@link #onReceive} 1080 * @param bundle the data to be passed to the new owner 1081 */ onTransferOwnershipComplete(@onNull Context context, @Nullable PersistableBundle bundle)1082 public void onTransferOwnershipComplete(@NonNull Context context, 1083 @Nullable PersistableBundle bundle) { 1084 } 1085 1086 /** 1087 * Called on the device owner when the ownership of one of its affiliated profiles is 1088 * transferred. 1089 * 1090 * <p>This can be used when transferring both device and profile ownership when using 1091 * work profile on a fully managed device. The process would look like this: 1092 * <ol> 1093 * <li>Transfer profile ownership</li> 1094 * <li>The device owner gets notified with this callback</li> 1095 * <li>Transfer device ownership</li> 1096 * <li>Both profile and device ownerships have been transferred</li> 1097 * </ol> 1098 * 1099 * @param context the running context as per {@link #onReceive} 1100 * @param user the {@link UserHandle} of the affiliated user 1101 * @see DevicePolicyManager#transferOwnership(ComponentName, ComponentName, PersistableBundle) 1102 */ onTransferAffiliatedProfileOwnershipComplete(@onNull Context context, @NonNull UserHandle user)1103 public void onTransferAffiliatedProfileOwnershipComplete(@NonNull Context context, 1104 @NonNull UserHandle user) { 1105 } 1106 1107 /** 1108 * Called to notify the state of operations that can be unsafe to execute has changed. 1109 * 1110 * <p><b>Note:/b> notice that the operation safety state might change between the time this 1111 * callback is received and the operation's method on {@link DevicePolicyManager} is called, so 1112 * calls to the latter could still throw a {@link UnsafeStateException} even when this method 1113 * is called with {@code isSafe} as {@code true} 1114 * 1115 * @param context the running context as per {@link #onReceive} 1116 * @param reason the reason an operation could be unsafe. 1117 * @param isSafe whether the operation is safe to be executed. 1118 */ onOperationSafetyStateChanged(@onNull Context context, @OperationSafetyReason int reason, boolean isSafe)1119 public void onOperationSafetyStateChanged(@NonNull Context context, 1120 @OperationSafetyReason int reason, boolean isSafe) { 1121 if (LOCAL_LOGV) { 1122 Log.v(TAG, String.format("onOperationSafetyStateChanged(): %s=%b", 1123 DevicePolicyManager.operationSafetyReasonToString(reason), isSafe)); 1124 } 1125 } 1126 onOperationSafetyStateChanged(Context context, Intent intent)1127 private void onOperationSafetyStateChanged(Context context, Intent intent) { 1128 if (!hasRequiredExtra(intent, EXTRA_OPERATION_SAFETY_REASON) 1129 || !hasRequiredExtra(intent, EXTRA_OPERATION_SAFETY_STATE)) { 1130 Log.w(TAG, "Igoring intent that's missing required extras"); 1131 return; 1132 } 1133 1134 int reason = intent.getIntExtra(EXTRA_OPERATION_SAFETY_REASON, 1135 DevicePolicyManager.OPERATION_SAFETY_REASON_NONE); 1136 if (!DevicePolicyManager.isValidOperationSafetyReason(reason)) { 1137 Log.wtf(TAG, "Received invalid reason on " + intent.getAction() + ": " + reason); 1138 return; 1139 } 1140 boolean isSafe = intent.getBooleanExtra(EXTRA_OPERATION_SAFETY_STATE, 1141 /* defaultValue=*/ false); 1142 onOperationSafetyStateChanged(context, reason, isSafe); 1143 } 1144 1145 /** 1146 * Called to notify a profile owner of an organization-owned device that it needs to acknowledge 1147 * device compliance to allow the user to turn the profile off if needed according to the 1148 * maximum profile time off policy. 1149 * 1150 * Default implementation acknowledges compliance immediately. DPC may prefer to override this 1151 * implementation to delay acknowledgement until a successful policy sync. Until compliance is 1152 * acknowledged the user is still free to turn the profile off, but the timer won't be reset, 1153 * so personal apps will be suspended sooner. This callback is delivered using a foreground 1154 * broadcast and should be handled quickly. 1155 * 1156 * @param context the running context as per {@link #onReceive} 1157 * @param intent The received intent as per {@link #onReceive}. 1158 * 1159 * @see DevicePolicyManager#acknowledgeDeviceCompliant() 1160 * @see DevicePolicyManager#isComplianceAcknowledgementRequired() 1161 * @see DevicePolicyManager#setManagedProfileMaximumTimeOff(ComponentName, long) 1162 */ onComplianceAcknowledgementRequired( @onNull Context context, @NonNull Intent intent)1163 public void onComplianceAcknowledgementRequired( 1164 @NonNull Context context, @NonNull Intent intent) { 1165 getManager(context).acknowledgeDeviceCompliant(); 1166 } 1167 hasRequiredExtra(Intent intent, String extra)1168 private boolean hasRequiredExtra(Intent intent, String extra) { 1169 if (intent.hasExtra(extra)) return true; 1170 1171 Log.wtf(TAG, "Missing '" + extra + "' on intent " + intent); 1172 return false; 1173 } 1174 1175 /** 1176 * Intercept standard device administrator broadcasts. Implementations 1177 * should not override this method; it is better to implement the 1178 * convenience callbacks for each action. 1179 */ 1180 @Override onReceive(@onNull Context context, @NonNull Intent intent)1181 public void onReceive(@NonNull Context context, @NonNull Intent intent) { 1182 String action = intent.getAction(); 1183 if (LOCAL_LOGV) { 1184 Log.v(TAG, getClass().getName() + ".onReceive(): received " + action + " on user " 1185 + context.getUserId()); 1186 } 1187 1188 if (ACTION_PASSWORD_CHANGED.equals(action)) { 1189 onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1190 } else if (ACTION_PASSWORD_FAILED.equals(action)) { 1191 onPasswordFailed(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1192 } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) { 1193 onPasswordSucceeded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1194 } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) { 1195 onEnabled(context, intent); 1196 } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) { 1197 CharSequence res = onDisableRequested(context, intent); 1198 if (res != null) { 1199 Bundle extras = getResultExtras(true); 1200 extras.putCharSequence(EXTRA_DISABLE_WARNING, res); 1201 } 1202 } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) { 1203 onDisabled(context, intent); 1204 } else if (ACTION_PASSWORD_EXPIRING.equals(action)) { 1205 onPasswordExpiring(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1206 } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) { 1207 onProfileProvisioningComplete(context, intent); 1208 } else if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) { 1209 int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1); 1210 Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI, android.net.Uri.class); 1211 String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS); 1212 String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias); 1213 setResultData(chosenAlias); 1214 } else if (ACTION_LOCK_TASK_ENTERING.equals(action)) { 1215 String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE); 1216 onLockTaskModeEntering(context, intent, pkg); 1217 } else if (ACTION_LOCK_TASK_EXITING.equals(action)) { 1218 onLockTaskModeExiting(context, intent); 1219 } else if (ACTION_NOTIFY_PENDING_SYSTEM_UPDATE.equals(action)) { 1220 long receivedTime = intent.getLongExtra(EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, -1); 1221 onSystemUpdatePending(context, intent, receivedTime); 1222 } else if (ACTION_BUGREPORT_SHARING_DECLINED.equals(action)) { 1223 onBugreportSharingDeclined(context, intent); 1224 } else if (ACTION_BUGREPORT_SHARE.equals(action)) { 1225 String bugreportFileHash = intent.getStringExtra(EXTRA_BUGREPORT_HASH); 1226 onBugreportShared(context, intent, bugreportFileHash); 1227 } else if (ACTION_BUGREPORT_FAILED.equals(action)) { 1228 int failureCode = intent.getIntExtra(EXTRA_BUGREPORT_FAILURE_REASON, 1229 BUGREPORT_FAILURE_FAILED_COMPLETING); 1230 onBugreportFailed(context, intent, failureCode); 1231 } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) { 1232 onSecurityLogsAvailable(context, intent); 1233 } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) { 1234 long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1); 1235 int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0); 1236 onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount); 1237 } else if (ACTION_USER_ADDED.equals(action)) { 1238 onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1239 } else if (ACTION_USER_REMOVED.equals(action)) { 1240 onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1241 } else if (ACTION_USER_STARTED.equals(action)) { 1242 onUserStarted(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1243 } else if (ACTION_USER_STOPPED.equals(action)) { 1244 onUserStopped(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1245 } else if (ACTION_USER_SWITCHED.equals(action)) { 1246 onUserSwitched(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1247 } else if (ACTION_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) { 1248 PersistableBundle bundle = 1249 intent.getParcelableExtra(EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE, android.os.PersistableBundle.class); 1250 onTransferOwnershipComplete(context, bundle); 1251 } else if (ACTION_AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) { 1252 onTransferAffiliatedProfileOwnershipComplete(context, 1253 intent.getParcelableExtra(Intent.EXTRA_USER, android.os.UserHandle.class)); 1254 } else if (ACTION_OPERATION_SAFETY_STATE_CHANGED.equals(action)) { 1255 onOperationSafetyStateChanged(context, intent); 1256 } else if (ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED.equals(action)) { 1257 onComplianceAcknowledgementRequired(context, intent); 1258 } 1259 } 1260 } 1261