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