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

Commit 312565f1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Stop LockSettingsService from calling DevicePolicyManager directly"

parents 716ebd4d 0f1e56de
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -153,4 +153,11 @@ public abstract class DevicePolicyManagerInternal {
     * Do not call it directly. Use {@link DevicePolicyCache#getInstance()} instead.
     */
    protected abstract DevicePolicyCache getDevicePolicyCache();

    /**
     * @return cached version of device state related to DPM that can be accessed without risking
     * deadlocks.
     * Do not call it directly. Use {@link DevicePolicyCache#getInstance()} instead.
     */
    protected abstract DeviceStateCache getDeviceStateCache();
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 com.android.server.LocalServices;

/**
 * Stores a copy of the set of device state maintained by {@link DevicePolicyManager} which
 * is not directly related to admin policies. This lives in its own class so that the state
 * can be accessed from any place without risking dead locks.
 *
 * @hide
 */
public abstract class DeviceStateCache {
    protected DeviceStateCache() {
    }

    /**
     * @return the instance.
     */
    public static DeviceStateCache getInstance() {
        final DevicePolicyManagerInternal dpmi =
                LocalServices.getService(DevicePolicyManagerInternal.class);
        return (dpmi != null) ? dpmi.getDeviceStateCache() : EmptyDeviceStateCache.INSTANCE;
    }

    /**
     * See {@link DevicePolicyManager#isDeviceProvisioned}
     */
    public abstract boolean isDeviceProvisioned();

    /**
     * Empty implementation.
     */
    private static class EmptyDeviceStateCache extends DeviceStateCache {
        private static final EmptyDeviceStateCache INSTANCE = new EmptyDeviceStateCache();

        @Override
        public boolean isDeviceProvisioned() {
            return false;
        }
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -85,12 +85,22 @@ public abstract class UserManagerInternal {
     */
    public abstract void setDeviceManaged(boolean isManaged);

    /**
     * Returns whether the device is managed by device owner.
     */
    public abstract boolean isDeviceManaged();

    /**
     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to update
     * whether the user is managed by profile owner.
     */
    public abstract void setUserManaged(int userId, boolean isManaged);

    /**
     * whether a profile owner manages this user.
     */
    public abstract boolean isUserManaged(int userId);

    /**
     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to omit
     * restriction check, because DevicePolicyManager must always be able to set user icon
+54 −42
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DeviceStateCache;
import android.app.admin.PasswordMetrics;
import android.app.backup.BackupManager;
import android.app.trust.IStrongAuthTracker;
@@ -76,6 +77,7 @@ import android.os.StrictMode;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.Settings;
@@ -429,6 +431,10 @@ public class LockSettingsService extends ILockSettings.Stub {
            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        }

        public UserManagerInternal getUserManagerInternal() {
            return LocalServices.getService(UserManagerInternal.class);
        }

        /**
         * Return the {@link DevicePolicyManager} object.
         *
@@ -440,6 +446,10 @@ public class LockSettingsService extends ILockSettings.Stub {
            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
        }

        public DeviceStateCache getDeviceStateCache() {
            return DeviceStateCache.getInstance();
        }

        public KeyStore getKeyStore() {
            return KeyStore.getInstance();
        }
@@ -1023,11 +1033,16 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    private void notifySeparateProfileChallengeChanged(int userId) {
        // LSS cannot call into DPM directly, otherwise it will cause deadlock.
        // In this case, calling DPM on a handler thread is OK since DPM doesn't
        // expect reportSeparateProfileChallengeChanged() to happen synchronously.
        mHandler.post(() -> {
            final DevicePolicyManagerInternal dpmi = LocalServices.getService(
                    DevicePolicyManagerInternal.class);
            if (dpmi != null) {
                dpmi.reportSeparateProfileChallengeChanged(userId);
            }
        });
    }

    @Override
@@ -2038,7 +2053,6 @@ public class LockSettingsService extends ILockSettings.Stub {
     * reporting the password changed.
     */
    private void notifyPasswordChanged(@UserIdInt int userId) {
        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
        mHandler.post(() -> {
            mInjector.getDevicePolicyManager().reportPasswordChanged(userId);
            LocalServices.getService(WindowManagerInternal.class).reportPasswordChanged(userId);
@@ -3026,29 +3040,30 @@ public class LockSettingsService extends ILockSettings.Stub {
        pw.decreaseIndent();
    }

    /**
     * Cryptographically disable escrow token support for the current user, if the user is not
     * managed (either user has a profile owner, or if device is managed). Do not disable
     * if we are running an automotive build.
     */
    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
        long ident = Binder.clearCallingIdentity();
        try {
        final UserManagerInternal userManagerInternal = mInjector.getUserManagerInternal();

        // Managed profile should have escrow enabled
            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
        if (userManagerInternal.isUserManaged(userId)) {
            Slog.i(TAG, "Managed profile can have escrow token");
            return;
        }
            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();

        // Devices with Device Owner should have escrow enabled on all users.
            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
        if (userManagerInternal.isDeviceManaged()) {
            Slog.i(TAG, "Corp-owned device can have escrow token");
            return;
        }
            // We could also have a profile owner on the given (non-managed) user for unicorn cases
            if (dpm.getProfileOwnerAsUser(userId) != null) {
                Slog.i(TAG, "User with profile owner can have escrow token");
                return;
            }

        // If the device is yet to be provisioned (still in SUW), there is still
        // a chance that Device Owner will be set on the device later, so postpone
        // disabling escrow token for now.
            if (!dpm.isDeviceProvisioned()) {
        if (!mInjector.getDeviceStateCache().isDeviceProvisioned()) {
            Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
            return;
        }
@@ -3063,9 +3078,6 @@ public class LockSettingsService extends ILockSettings.Stub {
        if (isSyntheticPasswordBasedCredentialLocked(userId)) {
            mSpManager.destroyEscrowData(userId);
        }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    private class DeviceProvisionedObserver extends ContentObserver {
+15 −0
Original line number Diff line number Diff line
@@ -3978,6 +3978,13 @@ public class UserManagerService extends IUserManager.Stub {
            }
        }

        @Override
        public boolean isDeviceManaged() {
            synchronized (mUsersLock) {
                return mIsDeviceManaged;
            }
        }

        @Override
        public void setUserManaged(@UserIdInt int userId, boolean isManaged) {
            synchronized (mUsersLock) {
@@ -3985,6 +3992,13 @@ public class UserManagerService extends IUserManager.Stub {
            }
        }

        @Override
        public boolean isUserManaged(@UserIdInt int userId) {
            synchronized (mUsersLock) {
                return mIsUserManaged.get(userId);
            }
        }

        @Override
        public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
            long ident = Binder.clearCallingIdentity();
@@ -4205,6 +4219,7 @@ public class UserManagerService extends IUserManager.Stub {
            return restrictions != null && restrictions.getBoolean(restrictionKey);
        }

        @Override
        public @Nullable UserInfo getUserInfo(@UserIdInt int userId) {
            UserData userData;
            synchronized (mUsersLock) {
Loading