Home | History | Annotate | Download | only in admin
      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      */
    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      */
    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      */
    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      */
    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      */
    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
    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      */
    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
    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      */
    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
    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      */
    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
    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      */
    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      */
    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
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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
   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