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