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

Commit 511e0d83 authored by justinzhang's avatar justinzhang
Browse files

DevicePolicyManager Authentication for Lock Task

Here we let DevicePolicyManager keep a list of tasks that are
allowed to start the lock task mode. This list can only be set by
a device owner app. The ActivityManager will call
DevicePolicyManager to check whether a given task can start the
lock task mode or not.

Change-Id: I650fdae43fc35bf9fd63452283f4e2bbadd11551
Bug: 14611303
parent 5b554f01
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5056,6 +5056,7 @@ package android.app.admin {
    method public boolean isActivePasswordSufficient();
    method public boolean isAdminActive(android.content.ComponentName);
    method public boolean isDeviceOwnerApp(java.lang.String);
    method public boolean isLockTaskPermitted(android.content.ComponentName);
    method public boolean isProfileOwnerApp(java.lang.String);
    method public void lockNow();
    method public void removeActiveAdmin(android.content.ComponentName);
@@ -5064,6 +5065,7 @@ package android.app.admin {
    method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
    method public void setCameraDisabled(android.content.ComponentName, boolean);
    method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
    method public void setLockTaskComponents(android.content.ComponentName[]) throws java.lang.SecurityException;
    method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
    method public void setMaximumTimeToLock(android.content.ComponentName, long);
    method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
+47 −0
Original line number Diff line number Diff line
@@ -2125,4 +2125,51 @@ public class DevicePolicyManager {

        return null;
    }

    /**
     * Sets which components may enter lock task mode.
     *
     * This function can only be called by the device owner or the profile owner.
     * @param components The list of components allowed to enter lock task mode
     */
    public void setLockTaskComponents(ComponentName[] components) throws SecurityException {
        if (mService != null) {
            try {
                mService.setLockTaskComponents(components);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed talking with device policy service", e);
            }
        }
    }

    /**
     * This function returns the list of components allowed to start the lock task mode.
     * @hide
     */
    public ComponentName[] getLockTaskComponents() {
        if (mService != null) {
            try {
                return mService.getLockTaskComponents();
            } catch (RemoteException e) {
                Log.w(TAG, "Failed talking with device policy service", e);
            }
        }
        return null;
    }

    /**
     * This function lets the caller know whether the given component is allowed to start the
     * lock task mode.
     * @param component The component to check
     */
    public boolean isLockTaskPermitted(ComponentName component) {
        if (mService != null) {
            try {
                return mService.isLockTaskPermitted(component);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed talking with device policy service", e);
            }
        }
        return false;
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -129,4 +129,8 @@ interface IDevicePolicyManager {

    void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled);
    String[] getAccountTypesWithManagementDisabled();

    void setLockTaskComponents(in ComponentName[] components);
    ComponentName[] getLockTaskComponents();
    boolean isLockTaskPermitted(in ComponentName component);
}
+89 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@@ -113,6 +114,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {

    private static final String DEVICE_POLICIES_XML = "device_policies.xml";

    private static final String LOCK_TASK_COMPONENTS_XML = "lock-task-component";

    private static final int REQUEST_EXPIRE_PASSWORD = 5571;

    private static final long MS_PER_DAY = 86400 * 1000;
@@ -182,6 +185,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        final ArrayList<ActiveAdmin> mAdminList
                = new ArrayList<ActiveAdmin>();

        // This is the list of component allowed to start lock task mode.
        final List<ComponentName> mLockTaskComponents = new ArrayList<ComponentName>();

        public DevicePolicyData(int userHandle) {
            mUserHandle = userHandle;
        }
@@ -955,6 +961,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                out.endTag(null, "active-password");
            }

            for (int i=0; i<policy.mLockTaskComponents.size(); i++) {
                ComponentName component = policy.mLockTaskComponents.get(i);
                out.startTag(null, LOCK_TASK_COMPONENTS_XML);
                out.attribute(null, "name", component.flattenToString());
                out.endTag(null, LOCK_TASK_COMPONENTS_XML);
            }

            out.endTag(null, "policies");

            out.endDocument();
@@ -1004,6 +1017,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
            type = parser.next();
            int outerDepth = parser.getDepth();
            policy.mLockTaskComponents.clear();
            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -1056,6 +1070,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    policy.mActivePasswordNonLetter = Integer.parseInt(
                            parser.getAttributeValue(null, "nonletter"));
                    XmlUtils.skipCurrentTag(parser);
                } else if (LOCK_TASK_COMPONENTS_XML.equals(tag)) {
                    policy.mLockTaskComponents.add
                        (ComponentName.unflattenFromString
                         (parser.getAttributeValue(null, "name")));
                    XmlUtils.skipCurrentTag(parser);
                } else {
                    Slog.w(LOG_TAG, "Unknown tag: " + tag);
                    XmlUtils.skipCurrentTag(parser);
@@ -3344,4 +3363,74 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return resultSet.toArray(new String[resultSet.size()]);
        }
    }

    /**
     * Sets which componets may enter lock task mode.
     *
     * This function can only be called by the device owner or the profile owner.
     * @param components The list of components allowed to enter lock task mode.
     */
    public void setLockTaskComponents(ComponentName[] components) throws SecurityException {
        // Get the package names of the caller.
        int uid = Binder.getCallingUid();
        String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);

        // Check whether any of the package name is the device owner or the profile owner.
        for (int i=0; i<packageNames.length; i++) {
            String packageName = packageNames[i];
            int userHandle = UserHandle.getUserId(uid);
            String profileOwnerPackage = getProfileOwner(userHandle);
            if (isDeviceOwner(packageName) ||
                (profileOwnerPackage != null && profileOwnerPackage.equals(packageName))) {

                // If a package name is the device owner or the profile owner,
                // we update the component list.
                DevicePolicyData policy = getUserData(userHandle);
                policy.mLockTaskComponents.clear();
                if (components != null) {
                    for (int j=0; j<components.length; j++) {
                        ComponentName component = components[j];
                        policy.mLockTaskComponents.add(component);
                    }
                }

                // Store the settings persistently.
                saveSettingsLocked(userHandle);
                return;
            }
        }
        throw new SecurityException();
    }

    /**
     * This function returns the list of components allowed to start the task lock mode.
     */
    public ComponentName[] getLockTaskComponents() {
        int userHandle = UserHandle.USER_OWNER;
        DevicePolicyData policy = getUserData(userHandle);
        ComponentName[] tempArray = policy.mLockTaskComponents.toArray(new ComponentName[0]);
        return tempArray;
    }

    /**
     * This function lets the caller know whether the given component is allowed to start the
     * lock task mode.
     * @param component The component to check
     */
    public boolean isLockTaskPermitted(ComponentName component) {
        // Get current user's devicepolicy
        int uid = Binder.getCallingUid();
        int userHandle = UserHandle.getUserId(uid);
        DevicePolicyData policy = getUserData(userHandle);
        for (int i=0; i<policy.mLockTaskComponents.size(); i++) {
            ComponentName lockTaskComponent = policy.mLockTaskComponents.get(i);

            // If the given component equals one of the component stored our device-owner-set
            // list, we allow this component to start the lock task mode.
            if (lockTaskComponent.getPackageName().equals(component.getPackageName())) {
                return true;
            }
        }
        return false;
    }
}