Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb458627 authored by Rubin Xu's avatar Rubin Xu Committed by Android (Google) Code Review
Browse files

Merge "Add three new delegation capabilities for profile/device owner"

parents 447bedc7 99a66a90
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -6448,6 +6448,13 @@ package android.app.admin {
    field public static final android.os.Parcelable.Creator<android.app.admin.ConnectEvent> CREATOR;
  }
  public class DelegatedAdminReceiver extends android.content.BroadcastReceiver {
    ctor public DelegatedAdminReceiver();
    method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String);
    method public void onNetworkLogsAvailable(android.content.Context, android.content.Intent, long, int);
    method public void onReceive(android.content.Context, android.content.Intent);
  }
  public final class DeviceAdminInfo implements android.os.Parcelable {
    ctor public DeviceAdminInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public int describeContents();
@@ -6510,11 +6517,13 @@ package android.app.admin {
    method public void onUserStarted(android.content.Context, android.content.Intent, android.os.UserHandle);
    method public void onUserStopped(android.content.Context, android.content.Intent, android.os.UserHandle);
    method public void onUserSwitched(android.content.Context, android.content.Intent, android.os.UserHandle);
    field public static final java.lang.String ACTION_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
    field public static final java.lang.String ACTION_DEVICE_ADMIN_ENABLED = "android.app.action.DEVICE_ADMIN_ENABLED";
    field public static final java.lang.String ACTION_LOCK_TASK_ENTERING = "android.app.action.LOCK_TASK_ENTERING";
    field public static final java.lang.String ACTION_LOCK_TASK_EXITING = "android.app.action.LOCK_TASK_EXITING";
    field public static final java.lang.String ACTION_NETWORK_LOGS_AVAILABLE = "android.app.action.NETWORK_LOGS_AVAILABLE";
    field public static final java.lang.String ACTION_PASSWORD_CHANGED = "android.app.action.ACTION_PASSWORD_CHANGED";
    field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING";
    field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
@@ -6759,10 +6768,13 @@ package android.app.admin {
    field public static final java.lang.String DELEGATION_APP_RESTRICTIONS = "delegation-app-restrictions";
    field public static final java.lang.String DELEGATION_BLOCK_UNINSTALL = "delegation-block-uninstall";
    field public static final java.lang.String DELEGATION_CERT_INSTALL = "delegation-cert-install";
    field public static final java.lang.String DELEGATION_CERT_SELECTION = "delegation-cert-selection";
    field public static final java.lang.String DELEGATION_ENABLE_SYSTEM_APP = "delegation-enable-system-app";
    field public static final java.lang.String DELEGATION_INSTALL_EXISTING_PACKAGE = "delegation-install-existing-package";
    field public static final java.lang.String DELEGATION_KEEP_UNINSTALLED_PACKAGES = "delegation-keep-uninstalled-packages";
    field public static final java.lang.String DELEGATION_NETWORK_LOGGING = "delegation-network-logging";
    field public static final java.lang.String DELEGATION_PACKAGE_ACCESS = "delegation-package-access";
    field public static final java.lang.String DELEGATION_PACKAGE_INSTALLATION = "delegation-package-installation";
    field public static final java.lang.String DELEGATION_PERMISSION_GRANT = "delegation-permission-grant";
    field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
    field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3
+129 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app.admin;

import static android.app.admin.DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS;
import static android.app.admin.DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE;
import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS;
import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID;
import static android.app.admin.DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URI;
import static android.app.admin.DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT;
import static android.app.admin.DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.security.KeyChain;
import android.util.Log;

/**
 * Base class for delegated apps to handle callbacks related to their delegated capabilities.
 *
 * <p>Delegated apps are apps that receive additional capabilities from the profile owner or
 * device owner apps. Some of these capabilities involve the framework calling into the apps.
 * To receive these callbacks, delegated apps should subclass this class and override the
 * appropriate methods here. The subclassed receiver needs to be published in the app's
 * manifest, with appropriate intent filters to mark which callbacks the receiver is interested
 * in. An app can have multiple receivers as long as they listen for disjoint set of callbacks.
 * For the manifest definitions, it must be protected by the
 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission to ensure only
 * the system can trigger these callbacks.
 *
 * <p>The callback methods happen on the main thread of the process.  Thus long running
 * operations must be done on another thread.  Note that because a receiver
 * is done once returning from its receive function, such long-running operations
 * should probably be done in a {@link Service}.
 *
 * @see DevicePolicyManager#setDelegatedScopes
 * @see DeviceAdminReceiver
 */
public class DelegatedAdminReceiver extends BroadcastReceiver {
    private static final String TAG = "DelegatedAdminReceiver";

    /**
     * Allows this receiver to select the alias for a private key and certificate pair for
     * authentication.  If this method returns null, the default {@link android.app.Activity} will
     * be shown that lets the user pick a private key and certificate pair.
     *
     * <p> This callback is only applicable if the delegated app has
     * {@link DevicePolicyManager#DELEGATION_CERT_SELECTION} capability. Additionally, it must
     * declare an intent fitler for {@link #ACTION_CHOOSE_PRIVATE_KEY_ALIAS} in the receiver's
     * manifest in order to receive this callback.
     *
     * @param context The running context as per {@link #onReceive}.
     * @param intent The received intent as per {@link #onReceive}.
     * @param uid The uid asking for the private key and certificate pair.
     * @param uri The URI to authenticate, may be null.
     * @param alias The alias preselected by the client, or null.
     * @return The private key alias to return and grant access to.
     * @see KeyChain#choosePrivateKeyAlias
     */
    public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
            String alias) {
        return null;
    }

    /**
     * Called each time a new batch of network logs can be retrieved. This callback method will only
     * ever be called when network logging is enabled. The logs can only be retrieved while network
     * logging is enabled.
     *
     * <p>If a secondary user or profile is created, this callback won't be received until all users
     * become affiliated again (even if network logging is enabled). It will also no longer be
     * possible to retrieve the network logs batch with the most recent {@code batchToken} provided
     * by this callback. See {@link DevicePolicyManager#setAffiliationIds}.
     *
     * <p> This callback is only applicable if the delegated app has
     * {@link DevicePolicyManager#DELEGATION_NETWORK_LOGGING} capability. Additionally, it must
     * declare an intent fitler for {@link #ACTION_NETWORK_LOGS_AVAILABLE} in the receiver's
     * manifest in order to receive this callback.
     *
     * @param context The running context as per {@link #onReceive}.
     * @param intent The received intent as per {@link #onReceive}.
     * @param batchToken The token representing the current batch of network logs.
     * @param networkLogsCount The total count of events in the current batch of network logs.
     * @see DevicePolicyManager#retrieveNetworkLogs
     */
    public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken,
            int networkLogsCount) {
    }

    /**
     * Intercept delegated device administrator broadcasts. Implementations should not override
     * this method; implement the convenience callbacks for each action instead.
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
            int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
            Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
            String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
            String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
            setResultData(chosenAlias);
        } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) {
            long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1);
            int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0);
            onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
        } else {
            Log.w(TAG, "Unhandled broadcast: " + action);
        }
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
    /**
     * Broadcast action: notify that a new batch of network logs is ready to be collected.
     * @see DeviceAdminReceiver#onNetworkLogsAvailable
     * @hide
     * @see DelegatedAdminReceiver#onNetworkLogsAvailable
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    @BroadcastBehavior(explicitOnly = true)
@@ -425,7 +425,11 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
     */
    public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1;

    /** @hide */
    /**
     * Broadcast action: notify that some app is attempting to choose a KeyChain key.
     * @see DeviceAdminReceiver#onChoosePrivateKeyAlias
     * @see DelegatedAdminReceiver#onChoosePrivateKeyAlias
     */
    public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS =
            "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";

+50 −11
Original line number Diff line number Diff line
@@ -1546,11 +1546,45 @@ public class DevicePolicyManager {

    /**
     * Delegation of management of uninstalled packages. This scope grants access to the
     * {@code #setKeepUninstalledPackages} and {@code #getKeepUninstalledPackages} APIs.
     * {@link #setKeepUninstalledPackages} and {@link #getKeepUninstalledPackages} APIs.
     */
    public static final String DELEGATION_KEEP_UNINSTALLED_PACKAGES =
            "delegation-keep-uninstalled-packages";

    /**
     * Grants access to {@link #setNetworkLoggingEnabled}, {@link #isNetworkLoggingEnabled} and
     * {@link #retrieveNetworkLogs}. Once granted the delegated app will start receiving
     * DelegatedAdminReceiver.onNetworkLogsAvailable() callback, and Device owner will no longer
     * receive the DeviceAdminReceiver.onNetworkLogsAvailable() callback.
     * There can be at most one app that has this delegation.
     * If another app already had delegated network logging access,
     * it will lose the delegation when a new app is delegated.
     *
     * <p> Can only be granted by Device Owner.
     */
    public static final String DELEGATION_NETWORK_LOGGING = "delegation-network-logging";

    /**
     * Grants access to selection of KeyChain certificates on behalf of requesting apps.
     * Once granted the app will start receiving
     * DelegatedAdminReceiver.onChoosePrivateKeyAlias. The caller (PO/DO) will
     * no longer receive {@link DeviceAdminReceiver#onChoosePrivateKeyAlias()}.
     * There can be at most one app that has this delegation.
     * If another app already had delegated certificate selection access,
     * it will lose the delegation when a new app is delegated.
     *
     * <p> Can be granted by Device Owner or Profile Owner.
     */
    public static final String DELEGATION_CERT_SELECTION = "delegation-cert-selection";


    /**
     * Delegation of silent APK installation via {@link android.content.pm.PackageInstaller} APIs.
     *
     * <p> Can only be delegated by Device Owner.
     */
    public static final String DELEGATION_PACKAGE_INSTALLATION = "delegation-package-installation";

    /**
     * No management for current user in-effect. This is the default.
     * @hide
@@ -9238,7 +9272,8 @@ public class DevicePolicyManager {
    }

    /**
     * Called by a device owner to control the network logging feature.
     * Called by a device owner or delegated app with {@link #DELEGATION_NETWORK_LOGGING} to
     * control the network logging feature.
     *
     * <p> Network logs contain DNS lookup and connect() library call events. The following library
     *     functions are recorded while network logging is active:
@@ -9275,16 +9310,17 @@ public class DevicePolicyManager {
     * all users to become affiliated. Therefore it's recommended that affiliation ids are set for
     * new users as soon as possible after provisioning via {@link #setAffiliationIds}.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
     *        {@code null} if called by a delegated app.
     * @param enabled whether network logging should be enabled or not.
     * @throws SecurityException if {@code admin} is not a device owner.
     * @see #setAffiliationIds
     * @see #retrieveNetworkLogs
     */
    public void setNetworkLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
    public void setNetworkLoggingEnabled(@Nullable ComponentName admin, boolean enabled) {
        throwIfParentInstance("setNetworkLoggingEnabled");
        try {
            mService.setNetworkLoggingEnabled(admin, enabled);
            mService.setNetworkLoggingEnabled(admin, mContext.getPackageName(), enabled);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
@@ -9294,7 +9330,8 @@ public class DevicePolicyManager {
     * Return whether network logging is enabled by a device owner.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Can only
     * be {@code null} if the caller has MANAGE_USERS permission.
     * be {@code null} if the caller is a delegated app with {@link #DELEGATION_NETWORK_LOGGING}
     * or has MANAGE_USERS permission.
     * @return {@code true} if network logging is enabled by device owner, {@code false} otherwise.
     * @throws SecurityException if {@code admin} is not a device owner and caller has
     * no MANAGE_USERS permission
@@ -9302,14 +9339,15 @@ public class DevicePolicyManager {
    public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) {
        throwIfParentInstance("isNetworkLoggingEnabled");
        try {
            return mService.isNetworkLoggingEnabled(admin);
            return mService.isNetworkLoggingEnabled(admin, mContext.getPackageName());
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Called by device owner to retrieve the most recent batch of network logging events.
     * Called by device owner or delegated app with {@link #DELEGATION_NETWORK_LOGGING} to retrieve
     * the most recent batch of network logging events.
     * A device owner has to provide a batchToken provided as part of
     * {@link DeviceAdminReceiver#onNetworkLogsAvailable} callback. If the token doesn't match the
     * token of the most recent available batch of logs, {@code null} will be returned.
@@ -9328,7 +9366,8 @@ public class DevicePolicyManager {
     * by {@link DeviceAdminReceiver#onNetworkLogsAvailable}. See
     * {@link DevicePolicyManager#setAffiliationIds}.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
     *        {@code null} if called by a delegated app.
     * @param batchToken A token of the batch to retrieve
     * @return A new batch of network logs which is a list of {@link NetworkEvent}. Returns
     *        {@code null} if the batch represented by batchToken is no longer available or if
@@ -9338,11 +9377,11 @@ public class DevicePolicyManager {
     * @see #setAffiliationIds
     * @see DeviceAdminReceiver#onNetworkLogsAvailable
     */
    public @Nullable List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin,
    public @Nullable List<NetworkEvent> retrieveNetworkLogs(@Nullable ComponentName admin,
            long batchToken) {
        throwIfParentInstance("retrieveNetworkLogs");
        try {
            return mService.retrieveNetworkLogs(admin, batchToken);
            return mService.retrieveNetworkLogs(admin, mContext.getPackageName(), batchToken);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
+3 −3
Original line number Diff line number Diff line
@@ -366,9 +366,9 @@ interface IDevicePolicyManager {
    void setBackupServiceEnabled(in ComponentName admin, boolean enabled);
    boolean isBackupServiceEnabled(in ComponentName admin);

    void setNetworkLoggingEnabled(in ComponentName admin, boolean enabled);
    boolean isNetworkLoggingEnabled(in ComponentName admin);
    List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin, long batchToken);
    void setNetworkLoggingEnabled(in ComponentName admin, in String packageName, boolean enabled);
    boolean isNetworkLoggingEnabled(in ComponentName admin, in String packageName);
    List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin, in String packageName, long batchToken);

    boolean bindDeviceAdminServiceAsUser(in ComponentName admin,
        IApplicationThread caller, IBinder token, in Intent service,
Loading