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

Commit 924e0e21 authored by Pavel Grafov's avatar Pavel Grafov
Browse files

Respect DISALLOW_UNIFIED_PASSWORD in Settings.

Bug: 63909482
Test: make ROBOTEST_FILTER=SecuritySettingsTest RunSettingsRoboTests
Test: make cts-verifier
Change-Id: Ia89501d5d5339c1340bee36a9bfb8ef72c4ee9b1
parent 2f7240ce
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@
                  xmlns:settings="http://schemas.android.com/apk/res-auto"
                  android:title="@string/security_settings_title">

    <SwitchPreference
    <com.android.settingslib.RestrictedSwitchPreference
        android:key="unification"
        android:title="@string/lock_settings_profile_unification_title"
        android:summary="@string/lock_settings_profile_unification_summary"
+18 −13
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComp
import com.android.settings.widget.GearPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.drawer.CategoryKey;

import java.util.ArrayList;
@@ -144,7 +145,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
    private ManagedLockPasswordProvider mManagedPasswordProvider;

    private SwitchPreference mVisiblePatternProfile;
    private SwitchPreference mUnifyProfile;
    private RestrictedSwitchPreference mUnifyProfile;

    private SwitchPreference mShowPassword;

@@ -319,7 +320,7 @@ public class SecuritySettings extends SettingsPreferenceFragment

        mVisiblePatternProfile =
                (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
        mUnifyProfile = (SwitchPreference) root.findPreference(KEY_UNIFICATION);
        mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION);

        // Append the rest of the settings
        addPreferencesFromResource(R.xml.security_settings_misc);
@@ -560,12 +561,19 @@ public class SecuritySettings extends SettingsPreferenceFragment
        mLocationcontroller.updateSummary();
    }

    private void updateUnificationPreference() {
    @VisibleForTesting
    void updateUnificationPreference() {
        if (mUnifyProfile != null) {
            mUnifyProfile.setChecked(!mLockPatternUtils.isSeparateProfileChallengeEnabled(
            final boolean separate =
                    mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
            mUnifyProfile.setChecked(!separate);
            if (separate) {
                mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
                        getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD,
                        mProfileChallengeUserId));
            }
        }
    }

    @Override
    public boolean onPreferenceTreeClick(Preference preference) {
@@ -930,16 +938,13 @@ public class SecuritySettings extends SettingsPreferenceFragment
                    .setPositiveButton(
                            compliant ? R.string.lock_settings_profile_unification_dialog_confirm
                            : R.string.lock_settings_profile_unification_dialog_uncompliant_confirm,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int whichButton) {
                            (dialog, whichButton) -> {
                                if (compliant) {
                                    parentFragment.launchConfirmDeviceLockForUnification();
                                }    else {
                                    parentFragment.unifyUncompliantLocks();
                                }
                            }
                            }
                    )
                    .setNegativeButton(R.string.cancel, null)
                    .create();
+56 −1
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
package com.android.settings.security;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -29,7 +31,9 @@ import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager.EnforcingUser;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
@@ -43,6 +47,9 @@ import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;

import org.junit.Before;
import org.junit.Test;
@@ -55,12 +62,15 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
        shadows = {
                ShadowLockPatternUtils.class
                ShadowLockPatternUtils.class,
                ShadowUserManager.class,
        })
public class SecuritySettingsTest {

@@ -187,4 +197,49 @@ public class SecuritySettingsTest {

        assertThat(keys).containsAllIn(niks);
    }

    @Test
    public void testUnifyLockRestriction() {
        // Set up instance under test.
        final Context context = spy(RuntimeEnvironment.application);
        final SecuritySettings securitySettings = spy(new SecuritySettings());
        when(securitySettings.getContext()).thenReturn(context);

        final int userId = 123;
        ReflectionHelpers.setField(securitySettings, "mProfileChallengeUserId", userId);

        final LockPatternUtils utils = mock(LockPatternUtils.class);
        when(utils.isSeparateProfileChallengeEnabled(userId)).thenReturn(true);
        ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);

        final RestrictedSwitchPreference unifyProfile = mock(RestrictedSwitchPreference.class);
        ReflectionHelpers.setField(securitySettings, "mUnifyProfile", unifyProfile);

        // Pretend that no admins enforce the restriction.
        ShadowUserManager.getShadow().setUserRestrictionSources(
                UserManager.DISALLOW_UNIFIED_PASSWORD,
                UserHandle.of(userId),
                Collections.emptyList());

        securitySettings.updateUnificationPreference();

        verify(unifyProfile).setDisabledByAdmin(null);

        reset(unifyProfile);

        // Pretend that the restriction is enforced by several admins. Having just one would
        // require more mocking of implementation details.
        final EnforcingUser enforcer1 = new EnforcingUser(
                userId, UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
        final EnforcingUser enforcer2 = new EnforcingUser(
                UserHandle.USER_SYSTEM, UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
        ShadowUserManager.getShadow().setUserRestrictionSources(
                UserManager.DISALLOW_UNIFIED_PASSWORD,
                UserHandle.of(userId),
                Arrays.asList(enforcer1, enforcer2));

        securitySettings.updateUnificationPreference();

        verify(unifyProfile).setDisabledByAdmin(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN);
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager.EnforcingUser;
import android.util.SparseArray;

import org.robolectric.RuntimeEnvironment;
@@ -31,14 +32,18 @@ import org.robolectric.shadow.api.Shadow;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Implements(UserManager.class)
public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager {

    private SparseArray<UserInfo> mUserInfos = new SparseArray<>();
    private boolean mAdminUser;
    private List<String> mRestrictions = new ArrayList<>();
    private final List<String> mRestrictions = new ArrayList<>();
    private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();


    public void setIsAdminUser(boolean isAdminUser) {
        mAdminUser = isAdminUser;
@@ -91,4 +96,15 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
        return (ShadowUserManager) Shadow.extract(
                RuntimeEnvironment.application.getSystemService(UserManager.class));
    }

    @Implementation
    public List<EnforcingUser> getUserRestrictionSources(
            String restrictionKey, UserHandle userHandle) {
        return mRestrictionSources.get(restrictionKey + userHandle.getIdentifier());
    }

    public void setUserRestrictionSources(
            String restrictionKey, UserHandle userHandle, List<EnforcingUser> enforcers) {
        mRestrictionSources.put(restrictionKey + userHandle.getIdentifier(), enforcers);
    }
}