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

Commit bed1828b authored by Kholoud Mohamed's avatar Kholoud Mohamed Committed by Android (Google) Code Review
Browse files

Merge changes Idb1d2d27,I60837e40

* changes:
  Migrate lock task policy APIs to coexistence
  Call device policy engine from DPMS
parents 71c5fa90 43fb625f
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -16,24 +16,35 @@

package com.android.server.devicepolicy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;

import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.Objects;

final class BooleanPolicySerializer extends PolicySerializer<Boolean> {

    @Override
    void saveToXml(TypedXmlSerializer serializer, String attributeName, Boolean value)
    void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Boolean value)
            throws IOException {
        Objects.requireNonNull(value);
        serializer.attributeBoolean(/* namespace= */ null, attributeName, value);
    }

    @Nullable
    @Override
    Boolean readFromXml(TypedXmlPullParser parser, String attributeName)
            throws XmlPullParserException {
    Boolean readFromXml(TypedXmlPullParser parser, String attributeName) {
        try {
            return parser.getAttributeBoolean(/* namespace= */ null, attributeName);
        } catch (XmlPullParserException e) {
            Log.e(DevicePolicyEngine.TAG, "Error parsing Boolean policy value", e);
            return null;
        }
    }
}
+169 −19
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED;
import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY;
import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT;
@@ -140,6 +141,7 @@ import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -309,6 +311,7 @@ import android.permission.PermissionControllerManager;
import android.provider.CalendarContract;
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsInternal;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Telephony;
@@ -712,6 +715,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    + "management app's authentication policy";
    private static final String NOT_SYSTEM_CALLER_MSG = "Only the system can %s";
    private static final String ENABLE_COEXISTENCE_FLAG = "enable_coexistence";
    private static final boolean DEFAULT_ENABLE_COEXISTENCE_FLAG = false;
    /**
     * For apps targeting U+
     * Enable multiple admins to coexist on the same device.
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
    static final long ENABLE_COEXISTENCE_CHANGE = 260560985L;
    final Context mContext;
    final Injector mInjector;
    final PolicyPathProvider mPathProvider;
@@ -795,6 +809,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    private final DeviceManagementResourcesProvider mDeviceManagementResourcesProvider;
    private final DevicePolicyManagementRoleObserver mDevicePolicyManagementRoleObserver;
    private final DevicePolicyEngine mDevicePolicyEngine;
    private static final boolean ENABLE_LOCK_GUARD = true;
    /**
@@ -1864,6 +1880,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        mUserData = new SparseArray<>();
        mOwners = makeOwners(injector, pathProvider);
        mDevicePolicyEngine = new DevicePolicyEngine(mContext);
        if (!mHasFeature) {
            // Skip the rest of the initialization
            mSetupContentObserver = null;
@@ -1908,6 +1926,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener());
        mDeviceManagementResourcesProvider.load();
        if (isCoexistenceFlagEnabled()) {
            mDevicePolicyEngine.load();
        }
        // The binder caches are not enabled until the first invalidation.
        invalidateBinderCaches();
@@ -7951,8 +7972,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller)
                || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner(caller));
        if (isCoexistenceEnabled(caller)) {
            mDevicePolicyEngine.setGlobalPolicy(
                    PolicyDefinition.AUTO_TIMEZONE,
                    // TODO(b/260573124): add correct enforcing admin when permission changes are
                    //  merged.
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(caller.getComponentName()),
                    enabled);
        } else {
            mInjector.binderWithCleanCallingIdentity(() ->
                    mInjector.settingsGlobalPutInt(Global.AUTO_TIME_ZONE, enabled ? 1 : 0));
        }
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_AUTO_TIME_ZONE)
@@ -12245,10 +12275,40 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        synchronized (getLockObject()) {
            enforceCanCallLockTaskLocked(caller);
            checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_PACKAGES);
        }
        if (isCoexistenceEnabled(caller)) {
            EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who);
            if (packages.length == 0) {
                mDevicePolicyEngine.removeLocalPolicy(
                        PolicyDefinition.LOCK_TASK,
                        admin,
                        caller.getUserId());
            } else {
                LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicy(
                        PolicyDefinition.LOCK_TASK,
                        caller.getUserId()).getPoliciesSetByAdmins().get(admin);
                LockTaskPolicy policy;
                if (currentPolicy == null) {
                    policy = new LockTaskPolicy(Set.of(packages));
                } else {
                    policy = currentPolicy.clone();
                    policy.setPackages(Set.of(packages));
                }
                mDevicePolicyEngine.setLocalPolicy(
                        PolicyDefinition.LOCK_TASK,
                        EnforcingAdmin.createEnterpriseEnforcingAdmin(who),
                        policy,
                        caller.getUserId());
            }
        } else {
            synchronized (getLockObject()) {
                final int userHandle = caller.getUserId();
                setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
            }
        }
    }
    private void setLockTaskPackagesLocked(int userHandle, List<String> packages) {
        DevicePolicyData policy = getUserData(userHandle);
@@ -12267,10 +12327,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        synchronized (getLockObject()) {
            enforceCanCallLockTaskLocked(caller);
        }
        if (isCoexistenceEnabled(caller)) {
            LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK, userHandle).getCurrentResolvedPolicy();
            if (policy == null) {
                return new String[0];
            } else {
                return policy.getPackages().toArray(new String[policy.getPackages().size()]);
            }
        } else {
            synchronized (getLockObject()) {
                final List<String> packages = getUserData(userHandle).mLockTaskPackages;
                return packages.toArray(new String[packages.size()]);
            }
        }
    }
    @Override
    public boolean isLockTaskPermitted(String pkg) {
@@ -12284,10 +12357,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        final int userId = mInjector.userHandleGetCallingUserId();
        // TODO(b/260560985): This is not the right check, as the flag could be enabled but there
        //  could be an admin that hasn't targeted U.
        if (isCoexistenceFlagEnabled()) {
            LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK, userId).getCurrentResolvedPolicy();
            if (policy == null) {
                return false;
            }
            return policy.getPackages().contains(pkg);
        } else {
            synchronized (getLockObject()) {
                return getUserData(userId).mLockTaskPackages.contains(pkg);
            }
        }
    }
    @Override
    public void setLockTaskFeatures(ComponentName who, int flags) {
@@ -12308,9 +12392,30 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            enforceCanCallLockTaskLocked(caller);
            enforceCanSetLockTaskFeaturesOnFinancedDevice(caller, flags);
            checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_FEATURES);
        }
        if (isCoexistenceEnabled(caller)) {
            EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who);
            LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK,
                    caller.getUserId()).getPoliciesSetByAdmins().get(admin);
            if (currentPolicy == null) {
                throw new IllegalArgumentException("Can't set a lock task flags without setting "
                        + "lock task packages first.");
            }
            LockTaskPolicy policy = currentPolicy.clone();
            policy.setFlags(flags);
            mDevicePolicyEngine.setLocalPolicy(
                    PolicyDefinition.LOCK_TASK,
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(who),
                    policy,
                    caller.getUserId());
        } else {
            synchronized (getLockObject()) {
                setLockTaskFeaturesLocked(userHandle, flags);
            }
        }
    }
    private void setLockTaskFeaturesLocked(int userHandle, int flags) {
        DevicePolicyData policy = getUserData(userHandle);
@@ -12326,9 +12431,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        final int userHandle = caller.getUserId();
        synchronized (getLockObject()) {
            enforceCanCallLockTaskLocked(caller);
        }
        if (isCoexistenceEnabled(caller)) {
            LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK, userHandle).getCurrentResolvedPolicy();
            if (policy == null) {
                // We default on the power button menu, in order to be consistent with pre-P
                // behaviour.
                return DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
            }
            return policy.getFlags();
        } else {
            synchronized (getLockObject()) {
                return getUserData(userHandle).mLockTaskFeatures;
            }
        }
    }
    private void maybeClearLockTaskPolicyLocked() {
        mInjector.binderWithCleanCallingIdentity(() -> {
@@ -13905,6 +14024,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            if (isFinancedDeviceOwner(caller)) {
                enforcePermissionGrantStateOnFinancedDevice(packageName, permission);
            }
        }
        if (isCoexistenceEnabled(caller)) {
            mDevicePolicyEngine.setLocalPolicy(
                    PolicyDefinition.PERMISSION_GRANT(packageName, permission),
                    // TODO(b/260573124): Add correct enforcing admin when permission changes are
                    //  merged, and don't forget to handle delegates! Enterprise admins assume
                    //  component name isn't null.
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(caller.getComponentName()),
                    grantState,
                    caller.getUserId());
            // TODO: update javadoc to reflect that callback no longer return success/failure
            callback.sendResult(Bundle.EMPTY);
        } else {
            synchronized (getLockObject()) {
            long ident = mInjector.binderClearCallingIdentity();
            try {
                boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId())
@@ -13921,14 +14054,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    callback.sendResult(null);
                    return;
                }
                if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
                if (grantState == PERMISSION_GRANT_STATE_GRANTED
                        || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
                        || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) {
                    AdminPermissionControlParams permissionParams =
                            new AdminPermissionControlParams(packageName, permission, grantState,
                            new AdminPermissionControlParams(packageName, permission,
                                    grantState,
                                    canAdminGrantSensorsPermissionsForUser(caller.getUserId()));
                    mInjector.getPermissionControllerManager(caller.getUserHandle())
                            .setRuntimePermissionGrantStateByDeviceAdmin(caller.getPackageName(),
                            .setRuntimePermissionGrantStateByDeviceAdmin(
                                    caller.getPackageName(),
                                    permissionParams, mContext.getMainExecutor(),
                                    (permissionWasSet) -> {
                                        if (isPostQAdmin && !permissionWasSet) {
@@ -13957,6 +14092,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                }
            }
        }
    }
    private void enforcePermissionGrantStateOnFinancedDevice(
            String packageName, String permission) {
@@ -19017,4 +19153,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return result;
        });
    }
    // TODO(b/260560985): properly gate coexistence changes
    private boolean isCoexistenceEnabled(CallerIdentity caller) {
        return isCoexistenceFlagEnabled()
                && mInjector.isChangeEnabled(
                        ENABLE_COEXISTENCE_CHANGE, caller.getPackageName(), caller.getUserId());
    }
    private boolean isCoexistenceFlagEnabled() {
        return DeviceConfig.getBoolean(
                NAMESPACE_DEVICE_POLICY_MANAGER,
                ENABLE_COEXISTENCE_FLAG,
                DEFAULT_ENABLE_COEXISTENCE_FLAG);
    }
}
+15 −4
Original line number Diff line number Diff line
@@ -16,24 +16,35 @@

package com.android.server.devicepolicy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;

import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.Objects;

final class IntegerPolicySerializer extends PolicySerializer<Integer> {

    @Override
    void saveToXml(TypedXmlSerializer serializer, String attributeName, Integer value)
    void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Integer value)
            throws IOException {
        Objects.requireNonNull(value);
        serializer.attributeInt(/* namespace= */ null, attributeName, value);
    }

    @Nullable
    @Override
    Integer readFromXml(TypedXmlPullParser parser, String attributeName)
            throws XmlPullParserException {
    Integer readFromXml(TypedXmlPullParser parser, String attributeName) {
        try {
            return parser.getAttributeInt(/* namespace= */ null, attributeName);
        } catch (XmlPullParserException e) {
            Log.e(DevicePolicyEngine.TAG, "Error parsing Integer policy value", e);
            return null;
        }
    }
}
+59 −27
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@

package com.android.server.devicepolicy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.util.Log;

import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -24,19 +27,16 @@ import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

final class LockTaskPolicy {
    private Set<String> mPackages;
    private int mFlags;
    static final int DEFAULT_LOCK_TASK_FLAG = DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
    private Set<String> mPackages = new HashSet<>();
    private int mFlags = DEFAULT_LOCK_TASK_FLAG;

    LockTaskPolicy(@Nullable Set<String> packages, int flags) {
        mPackages = packages;
        mFlags = flags;
    }

    @Nullable
    @NonNull
    Set<String> getPackages() {
        return mPackages;
    }
@@ -45,14 +45,33 @@ final class LockTaskPolicy {
        return mFlags;
    }

    void setPackages(Set<String> packages) {
        mPackages = packages;
    LockTaskPolicy(Set<String> packages) {
        Objects.requireNonNull(packages);
        mPackages.addAll(packages);
    }

    private LockTaskPolicy(Set<String> packages, int flags) {
        Objects.requireNonNull(packages);
        mPackages = new HashSet<>(packages);
        mFlags = flags;
    }

    void setPackages(@NonNull Set<String> packages) {
        Objects.requireNonNull(packages);
        mPackages = new HashSet<>(packages);
    }

    void setFlags(int flags) {
        mFlags = flags;
    }

    @Override
    public LockTaskPolicy clone() {
        LockTaskPolicy policy = new LockTaskPolicy(mPackages);
        policy.setFlags(mFlags);
        return policy;
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) return true;
@@ -67,6 +86,11 @@ final class LockTaskPolicy {
        return Objects.hash(mPackages, mFlags);
    }

    @Override
    public String toString() {
        return "mPackages= " + String.join(", ", mPackages) + "; mFlags= " + mFlags;
    }

    static final class LockTaskPolicySerializer extends PolicySerializer<LockTaskPolicy> {

        private static final String ATTR_PACKAGES = ":packages";
@@ -74,15 +98,17 @@ final class LockTaskPolicy {
        private static final String ATTR_FLAGS = ":flags";

        @Override
        void saveToXml(
                TypedXmlSerializer serializer, String attributeNamePrefix, LockTaskPolicy value)
                throws IOException {
            if (value.mPackages != null) {
        void saveToXml(TypedXmlSerializer serializer, String attributeNamePrefix,
                @NonNull LockTaskPolicy value) throws IOException {
            Objects.requireNonNull(value);
            if (value.mPackages == null || value.mPackages.isEmpty()) {
                throw new IllegalArgumentException("Error saving LockTaskPolicy to file, lock task "
                        + "packages must be present");
            }
            serializer.attribute(
                    /* namespace= */ null,
                    attributeNamePrefix + ATTR_PACKAGES,
                    String.join(ATTR_PACKAGES_SEPARATOR, value.mPackages));
            }
            serializer.attributeInt(
                    /* namespace= */ null,
                    attributeNamePrefix + ATTR_FLAGS,
@@ -90,18 +116,24 @@ final class LockTaskPolicy {
        }

        @Override
        LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix)
                throws XmlPullParserException {
        LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
            String packagesStr = parser.getAttributeValue(
                    /* namespace= */ null,
                    attributeNamePrefix + ATTR_PACKAGES);
            Set<String> packages = packagesStr == null
                    ? null
                    : Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
            if (packagesStr == null) {
                Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value.");
                return null;
            }
            Set<String> packages = Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
            try {
                int flags = parser.getAttributeInt(
                        /* namespace= */ null,
                        attributeNamePrefix + ATTR_FLAGS);
                return new LockTaskPolicy(packages, flags);
            } catch (XmlPullParserException e) {
                Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value", e);
                return null;
            }
        }
    }
}
+2 −4
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@ import com.android.internal.util.function.QuadFunction;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
@@ -225,8 +223,8 @@ final class PolicyDefinition<V> {
        mPolicySerializer.saveToXml(serializer, attributeName, value);
    }

    V readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName)
            throws XmlPullParserException {
    @Nullable
    V readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName) {
        return mPolicySerializer.readFromXml(parser, attributeName);
    }
}
Loading