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

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

Merge "Improve work profile unification flow" into rvc-dev

parents 566d9f49 f535e87e
Loading
Loading
Loading
Loading
+60 −30
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ public class ChooseLockGeneric extends SettingsActivity {
        static final int SKIP_FINGERPRINT_REQUEST = 104;

        private ChooseLockSettingsHelper mChooseLockSettingsHelper;
        private DevicePolicyManager mDPM;
        private DevicePolicyManager mDpm;
        private boolean mHasChallenge = false;
        private long mChallenge;
        private boolean mPasswordConfirmed = false;
@@ -158,6 +158,8 @@ public class ChooseLockGeneric extends SettingsActivity {
        private boolean mIsSetNewPassword = false;
        private UserManager mUserManager;
        private ChooseLockGenericController mController;
        private int mUnificationProfileId = UserHandle.USER_NULL;
        private LockscreenCredential mUnificationProfileCredential;

        /**
         * From intent extra {@link ChooseLockSettingsHelper#EXTRA_KEY_REQUESTED_MIN_COMPLEXITY}.
@@ -185,48 +187,57 @@ public class ChooseLockGeneric extends SettingsActivity {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final Activity activity = getActivity();
            final Bundle arguments = getArguments();
            if (!WizardManagerHelper.isDeviceProvisioned(activity)
                    && !canRunBeforeDeviceProvisioned()) {
                Log.i(TAG, "Refusing to start because device is not provisioned");
                activity.finish();
                return;
            }

            String chooseLockAction = getActivity().getIntent().getAction();
            mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity());
            mFaceManager = Utils.getFaceManagerOrNull(getActivity());
            mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
            mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
            mLockPatternUtils = new LockPatternUtils(getActivity());
            final Intent intent = activity.getIntent();
            String chooseLockAction = intent.getAction();
            mFingerprintManager = Utils.getFingerprintManagerOrNull(activity);
            mFaceManager = Utils.getFaceManagerOrNull(activity);
            mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
            mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity);
            mLockPatternUtils = new LockPatternUtils(activity);
            mIsSetNewPassword = ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
                    || ACTION_SET_NEW_PASSWORD.equals(chooseLockAction);

            // Defaults to needing to confirm credentials
            final boolean confirmCredentials = getActivity().getIntent()
            final boolean confirmCredentials = intent
                .getBooleanExtra(CONFIRM_CREDENTIALS, true);
            if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
            if (activity instanceof ChooseLockGeneric.InternalActivity) {
                mPasswordConfirmed = !confirmCredentials;
                mUserPassword = getActivity().getIntent().getParcelableExtra(
                mUserPassword = intent.getParcelableExtra(
                        ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
            }

            mHasChallenge = getActivity().getIntent().getBooleanExtra(
            mHasChallenge = intent.getBooleanExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
            mChallenge = getActivity().getIntent().getLongExtra(
            mChallenge = intent.getLongExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
            mForFingerprint = getActivity().getIntent().getBooleanExtra(
            mForFingerprint = intent.getBooleanExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
            mForFace = getActivity().getIntent().getBooleanExtra(
            mForFace = intent.getBooleanExtra(
                    ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false);
            mRequestedMinComplexity = getActivity().getIntent()
            mRequestedMinComplexity = intent
                    .getIntExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
            mCallerAppName =
                    getActivity().getIntent().getStringExtra(EXTRA_KEY_CALLER_APP_NAME);
            mIsCallingAppAdmin = getActivity().getIntent()
                    intent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME);
            mIsCallingAppAdmin = intent
                    .getBooleanExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, /* defValue= */ false);
            mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
            mForChangeCredRequiredForBoot = arguments != null && arguments.getBoolean(
                    ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
            mUserManager = UserManager.get(getActivity());
            mUserManager = UserManager.get(activity);

            if (arguments != null) {
                mUnificationProfileCredential = (LockscreenCredential) arguments.getParcelable(
                        ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL);
                mUnificationProfileId = arguments.getInt(
                        ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID,
                        UserHandle.USER_NULL);
            }

            if (savedInstanceState != null) {
                mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
@@ -242,19 +253,19 @@ public class ChooseLockGeneric extends SettingsActivity {
            //    from Settings app itself.
            // c) Otherwise, use UserHandle.myUserId().
            mUserId = Utils.getSecureTargetUser(
                    getActivity().getActivityToken(),
                    UserManager.get(getActivity()),
                    getArguments(),
                    getActivity().getIntent().getExtras()).getIdentifier();
                    activity.getActivityToken(),
                    UserManager.get(activity),
                    arguments,
                    intent.getExtras()).getIdentifier();
            mController = new ChooseLockGenericController(
                    getContext(), mUserId, mRequestedMinComplexity, mLockPatternUtils);
            if (ACTION_SET_NEW_PASSWORD.equals(chooseLockAction)
                    && UserManager.get(getActivity()).isManagedProfile(mUserId)
                    && UserManager.get(activity).isManagedProfile(mUserId)
                    && mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
                getActivity().setTitle(R.string.lock_settings_picker_title_profile);
                activity.setTitle(R.string.lock_settings_picker_title_profile);
            }

            mManagedPasswordProvider = ManagedLockPasswordProvider.get(getActivity(), mUserId);
            mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, mUserId);

            if (mPasswordConfirmed) {
                updatePreferencesOrFinish(savedInstanceState != null);
@@ -264,9 +275,9 @@ public class ChooseLockGeneric extends SettingsActivity {
                }
            } else if (!mWaitingForConfirmation) {
                ChooseLockSettingsHelper helper =
                        new ChooseLockSettingsHelper(this.getActivity(), this);
                        new ChooseLockSettingsHelper(activity, this);
                boolean managedProfileWithUnifiedLock =
                        UserManager.get(getActivity()).isManagedProfile(mUserId)
                        UserManager.get(activity).isManagedProfile(mUserId)
                        && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId);
                boolean skipConfirmation = managedProfileWithUnifiedLock && !mIsSetNewPassword;
                if (skipConfirmation
@@ -632,9 +643,22 @@ public class ChooseLockGeneric extends SettingsActivity {
                boolean hideDisabled) {
            final PreferenceScreen entries = getPreferenceScreen();

            int adminEnforcedQuality = mDPM.getPasswordQuality(null, mUserId);
            int adminEnforcedQuality = mDpm.getPasswordQuality(null, mUserId);
            EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(
                    getActivity(), mUserId);
            // If we are to unify a work challenge at the end of the credential enrollment, manually
            // merge any password policy from that profile here, so we are enrolling a compliant
            // password. This is because once unified, the profile's password policy will
            // be enforced on the new credential.
            if (mUnificationProfileId != UserHandle.USER_NULL) {
                int profileEnforceQuality = mDpm.getPasswordQuality(null, mUnificationProfileId);
                if (profileEnforceQuality > adminEnforcedQuality) {
                    adminEnforcedQuality = profileEnforceQuality;
                    enforcedAdmin = EnforcedAdmin.combine(enforcedAdmin,
                            RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(
                                    getActivity(), mUnificationProfileId));
                }
            }

            for (ScreenLockType lock : ScreenLockType.values()) {
                String key = lock.preferenceKey;
@@ -704,6 +728,9 @@ public class ChooseLockGeneric extends SettingsActivity {
            if (mUserPassword != null) {
                builder.setPassword(mUserPassword);
            }
            if (mUnificationProfileId != UserHandle.USER_NULL) {
                builder.setProfileToUnify(mUnificationProfileId, mUnificationProfileCredential);
            }
            return builder.build();
        }

@@ -719,6 +746,9 @@ public class ChooseLockGeneric extends SettingsActivity {
            if (mUserPassword != null) {
                builder.setPattern(mUserPassword);
            }
            if (mUnificationProfileId != UserHandle.USER_NULL) {
                builder.setProfileToUnify(mUnificationProfileId, mUnificationProfileCredential);
            }
            return builder.build();
        }

+39 −1
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ import static com.android.internal.widget.PasswordValidationError.RECENTLY_USED;
import static com.android.internal.widget.PasswordValidationError.TOO_LONG;
import static com.android.internal.widget.PasswordValidationError.TOO_SHORT;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
@@ -46,6 +48,7 @@ import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.UserHandle;
import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
@@ -153,6 +156,18 @@ public class ChooseLockPassword extends SettingsActivity {
            return this;
        }

        /**
         * Configures the launch such that at the end of the password enrollment, one of its
         * managed profile (specified by {@code profileId}) will have its lockscreen unified
         * to the parent user. The profile's current lockscreen credential needs to be specified by
         * {@code credential}.
         */
        public IntentBuilder setProfileToUnify(int profileId, LockscreenCredential credential) {
            mIntent.putExtra(EXTRA_KEY_UNIFICATION_PROFILE_ID, profileId);
            mIntent.putExtra(EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL, credential);
            return this;
        }

        public Intent build() {
            return mIntent;
        }
@@ -208,6 +223,7 @@ public class ChooseLockPassword extends SettingsActivity {
        @PasswordComplexity private int mMinComplexity = PASSWORD_COMPLEXITY_NONE;
        protected int mUserId;
        private byte[] mPasswordHistoryHashFactor;
        private int mUnificationProfileId = UserHandle.USER_NULL;

        private LockPatternUtils mLockPatternUtils;
        private SaveAndFinishWorker mSaveAndFinishWorker;
@@ -367,8 +383,19 @@ public class ChooseLockPassword extends SettingsActivity {

            mRequestedQuality = intent.getIntExtra(
                    LockPatternUtils.PASSWORD_TYPE_KEY, PASSWORD_QUALITY_NUMERIC);
            mUnificationProfileId = intent.getIntExtra(
                    EXTRA_KEY_UNIFICATION_PROFILE_ID, UserHandle.USER_NULL);

            mMinMetrics = mLockPatternUtils.getRequestedPasswordMetrics(mUserId);
            // If we are to unify a work challenge at the end of the credential enrollment, manually
            // merge any password policy from that profile here, so we are enrolling a compliant
            // password. This is because once unified, the profile's password policy will
            // be enforced on the new credential.
            if (mUnificationProfileId != UserHandle.USER_NULL) {
                mMinMetrics.maxWith(
                        mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
            }

            mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());

            if (intent.getBooleanExtra(
@@ -833,8 +860,16 @@ public class ChooseLockPassword extends SettingsActivity {
                    FRAGMENT_TAG_SAVE_AND_FINISH).commit();
            getFragmentManager().executePendingTransactions();

            final boolean required = getActivity().getIntent().getBooleanExtra(
            final Intent intent = getActivity().getIntent();
            final boolean required = intent.getBooleanExtra(
                    EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
            if (mUnificationProfileId != UserHandle.USER_NULL) {
                try (LockscreenCredential profileCredential = (LockscreenCredential)
                        intent.getParcelableExtra(EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL)) {
                    mSaveAndFinishWorker.setProfileToUnify(mUnificationProfileId,
                            profileCredential);
                }
            }
            mSaveAndFinishWorker.start(mLockPatternUtils, required, mHasChallenge, mChallenge,
                    mChosenPassword, mCurrentCredential, mUserId);
        }
@@ -912,6 +947,9 @@ public class ChooseLockPassword extends SettingsActivity {
        protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
            final boolean success = mUtils.setLockCredential(
                    mChosenPassword, mCurrentCredential, mUserId);
            if (success) {
                unifyProfileCredentialIfRequested();
            }
            Intent result = null;
            if (success && mHasChallenge) {
                byte[] token;
+32 −1
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.settings.password;

import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID;

import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -23,6 +26,7 @@ import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Resources.Theme;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.Log;
import android.util.Pair;
import android.util.TypedValue;
@@ -50,6 +54,7 @@ import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.notification.RedactionInterstitial;
import com.android.settings.password.ChooseLockPassword.IntentBuilder;

import com.google.android.collect.Lists;
import com.google.android.setupcompat.template.FooterBarMixin;
@@ -130,6 +135,19 @@ public class ChooseLockPattern extends SettingsActivity {
            return this;
        }

        /**
         * Configures the launch such that at the end of the pattern enrollment, one of its
         * managed profile (specified by {@code profileId}) will have its lockscreen unified
         * to the parent user. The profile's current lockscreen credential needs to be specified by
         * {@code credential}.
         */
        public IntentBuilder setProfileToUnify(int profileId, LockscreenCredential credential) {
            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID, profileId);
            mIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL,
                    credential);
            return this;
        }

        public Intent build() {
            return mIntent;
        }
@@ -810,8 +828,18 @@ public class ChooseLockPattern extends SettingsActivity {
                    FRAGMENT_TAG_SAVE_AND_FINISH).commit();
            getFragmentManager().executePendingTransactions();

            final boolean required = getActivity().getIntent().getBooleanExtra(
            final Intent intent = getActivity().getIntent();
            final boolean required = intent.getBooleanExtra(
                    EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
            if (intent.hasExtra(EXTRA_KEY_UNIFICATION_PROFILE_ID)) {
                try (LockscreenCredential profileCredential = (LockscreenCredential)
                        intent.getParcelableExtra(EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL)) {
                    mSaveAndFinishWorker.setProfileToUnify(
                            intent.getIntExtra(EXTRA_KEY_UNIFICATION_PROFILE_ID,
                                    UserHandle.USER_NULL),
                            profileCredential);
                }
            }
            mSaveAndFinishWorker.start(mChooseLockSettingsHelper.utils(), required,
                    mHasChallenge, mChallenge, mChosenPattern, mCurrentCredential, mUserId);
        }
@@ -863,6 +891,9 @@ public class ChooseLockPattern extends SettingsActivity {
            final int userId = mUserId;
            final boolean success = mUtils.setLockCredential(mChosenPattern, mCurrentCredential,
                    userId);
            if (success) {
                unifyProfileCredentialIfRequested();
            }
            Intent result = null;
            if (success && mHasChallenge) {
                byte[] token;
+12 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import androidx.fragment.app.Fragment;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;

import com.google.android.setupcompat.util.WizardManagerHelper;

@@ -49,6 +50,17 @@ public final class ChooseLockSettingsHelper {
    public static final String EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT = "for_cred_req_boot";
    public static final String EXTRA_KEY_FOREGROUND_ONLY = "foreground_only";

    /**
     * When EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL and EXTRA_KEY_UNIFICATION_PROFILE_ID are
     * provided to ChooseLockGeneric as fragment arguments {@link SubSettingLauncher#setArguments},
     * at the end of the password change flow, the supplied profile user
     * (EXTRA_KEY_UNIFICATION_PROFILE_ID) will be unified to its parent. The current profile
     * password is supplied by EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL.
     */
    public static final String EXTRA_KEY_UNIFICATION_PROFILE_ID = "unification_profile_id";
    public static final String EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL =
            "unification_profile_credential";

    /**
     * Intent extra for passing the requested min password complexity to later steps in the set new
     * screen lock flow.
+19 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Pair;
import android.widget.Toast;
@@ -27,6 +28,7 @@ import android.widget.Toast;
import androidx.fragment.app.Fragment;

import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;

/**
@@ -44,6 +46,8 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
    protected long mChallenge;
    protected boolean mWasSecureBefore;
    protected int mUserId;
    protected int mUnificationProfileId = UserHandle.USER_NULL;
    protected LockscreenCredential mUnificationProfileCredential;

    private boolean mBlocking;

@@ -106,12 +110,27 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
        if (mListener != null) {
            mListener.onChosenLockSaveFinished(mWasSecureBefore, mResultData);
        }
        if (mUnificationProfileCredential != null) {
            mUnificationProfileCredential.zeroize();
        }
    }

    public void setBlocking(boolean blocking) {
        mBlocking = blocking;
    }

    public void setProfileToUnify(int profileId, LockscreenCredential credential) {
        mUnificationProfileId = profileId;
        mUnificationProfileCredential = credential.duplicate();
    }

    protected void unifyProfileCredentialIfRequested() {
        if (mUnificationProfileId != UserHandle.USER_NULL) {
            mUtils.setSeparateProfileChallengeEnabled(mUnificationProfileId, false,
                    mUnificationProfileCredential);
        }
    }

    private class Task extends AsyncTask<Void, Void, Pair<Boolean, Intent>> {

        @Override
Loading