Merge sub pages for lock/unlock into 1 xml.

And create PreferenceControllers for each setting

The page is still pretty janky and controllers are invoked manually.
Next CL will clean these up.

Bug: 32953042
Test: TODO
Change-Id: I1d7478324f5de4fdb464d79f89086f7e79c0ee67
This commit is contained in:
Fan Zhang
2018-01-03 15:02:02 -08:00
parent 05d1b4c00e
commit 928ddbe731
21 changed files with 1050 additions and 601 deletions

View File

@@ -18,7 +18,7 @@
set height to 0. This will be used in preference category without title in order to remove set height to 0. This will be used in preference category without title in order to remove
extra 32dp blank --> extra 32dp blank -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android" <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+android:id/title" android:id="@android:id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:textAppearance="@android:style/TextAppearance.Material.Body2" android:textAppearance="@android:style/TextAppearance.Material.Body2"

View File

@@ -24,29 +24,71 @@
<!-- security_settings_status.xml --> <!-- security_settings_status.xml -->
<PreferenceCategory <PreferenceCategory
android:order="-10"
android:key="security_status" android:key="security_status"
android:title="@string/security_status_title" /> android:title="@string/security_status_title" />
<!-- TODO Need security section -->
<PreferenceCategory <PreferenceCategory
android:order="1"
android:key="dashboard_tile_placeholder" />
<!-- security section -->
<PreferenceCategory
android:order="10"
android:key="security_category" android:key="security_category"
android:title="@string/lock_settings_title"> android:title="@string/lock_settings_title">
<!-- security_settings_chooser -->
<com.android.settings.widget.GearPreference <com.android.settings.widget.GearPreference
android:key="unlock_set_or_change" android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_title" android:title="@string/unlock_set_unlock_launch_picker_title"
android:summary="@string/unlock_set_unlock_mode_none" android:summary="@string/unlock_set_unlock_mode_none"
settings:keywords="@string/keywords_lockscreen" /> settings:keywords="@string/keywords_lockscreen" />
<Preference android:key="lockscreen_preferences" <Preference
android:key="lockscreen_preferences"
android:title="@string/lockscreen_settings_title" android:title="@string/lockscreen_settings_title"
android:fragment="com.android.settings.security.LockscreenDashboardFragment" /> android:fragment="com.android.settings.security.LockscreenDashboardFragment" />
<Preference
android:key="fingerprint_settings"
android:title="@string/security_settings_fingerprint_preference_title"
android:summary="@string/summary_placeholder" />
</PreferenceCategory>
<!-- work profile security section -->
<PreferenceCategory
android:order="20"
android:key="security_category_profile"
android:title="@string/lock_settings_profile_title">
<!-- security_settings_unification -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="unification"
android:title="@string/lock_settings_profile_unification_title"
android:summary="@string/lock_settings_profile_unification_summary"
settings:keywords="@string/keywords_unification" />
<com.android.settingslib.RestrictedPreference
android:key="unlock_set_or_change_profile"
android:title="@string/unlock_set_unlock_launch_picker_title_profile"
android:summary="@string/unlock_set_unlock_mode_pattern"
settings:keywords="@string/keywords_lockscreen" />
<SwitchPreference
android:key="visiblepattern_profile"
android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile" />
<Preference
android:key="fingerprint_settings_profile"
android:title="@string/security_settings_fingerprint_preference_title"
android:summary="@string/summary_placeholder" />
</PreferenceCategory> </PreferenceCategory>
<!-- security_settings_misc.xml --> <!-- security_settings_misc.xml -->
<PreferenceCategory <PreferenceCategory
android:order="30"
android:key="security_settings_misc_category" android:key="security_settings_misc_category"
android:title="@string/security_passwords_title"> android:title="@string/security_passwords_title">
@@ -64,6 +106,7 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:order="40"
android:key="security_settings_device_admin_category"> android:key="security_settings_device_admin_category">
<Preference android:key="manage_device_admin" <Preference android:key="manage_device_admin"
@@ -78,33 +121,42 @@
</PreferenceCategory> </PreferenceCategory>
<Preference android:key="sim_lock_settings" <Preference
android:order="50"
android:key="sim_lock_settings"
android:title="@string/sim_lock_settings_category"> android:title="@string/sim_lock_settings_category">
<intent android:action="android.intent.action.MAIN" <intent
android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings" android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.Settings$IccLockSettingsActivity" /> android:targetClass="com.android.settings.Settings$IccLockSettingsActivity" />
</Preference> </Preference>
<Preference <Preference
android:order="60"
android:key="encryption_and_credential" android:key="encryption_and_credential"
android:title="@string/encryption_and_credential_settings_title" android:title="@string/encryption_and_credential_settings_title"
android:summary="@string/encryption_and_credential_settings_summary" android:summary="@string/encryption_and_credential_settings_summary"
android:fragment="com.android.settings.security.EncryptionAndCredential" /> android:fragment="com.android.settings.security.EncryptionAndCredential" />
<Preference android:key="manage_trust_agents" <Preference
android:order="70"
android:key="manage_trust_agents"
android:title="@string/manage_trust_agents" android:title="@string/manage_trust_agents"
android:persistent="false" android:persistent="false"
android:fragment="com.android.settings.security.trustagent.TrustAgentSettings" /> android:fragment="com.android.settings.security.trustagent.TrustAgentSettings" />
<Preference <Preference
android:order="80"
android:key="screen_pinning_settings" android:key="screen_pinning_settings"
android:title="@string/screen_pinning_title" android:title="@string/screen_pinning_title"
android:summary="@string/summary_placeholder" android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.security.ScreenPinningSettings" /> android:fragment="com.android.settings.security.ScreenPinningSettings" />
<Preference android:key="security_misc_usage_access" <Preference
android:order="90"
android:key="security_misc_usage_access"
android:title="@string/usage_access_title" android:title="@string/usage_access_title"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"> android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
<extra <extra

View File

@@ -98,10 +98,11 @@ public class BluetoothSwitchPreferenceController extends TogglePreferenceControl
} }
@Override @Override
public void setChecked(boolean isChecked) { public boolean setChecked(boolean isChecked) {
if (mBluetoothAdapter != null) { if (mBluetoothAdapter != null) {
mBluetoothAdapter.setBluetoothEnabled(isChecked); mBluetoothAdapter.setBluetoothEnabled(isChecked);
} }
return true;
} }
/** /**

View File

@@ -40,8 +40,9 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle
* Set the Setting to {@param isChecked} * Set the Setting to {@param isChecked}
* *
* @param isChecked Is {@true} when the setting should be enabled. * @param isChecked Is {@true} when the setting should be enabled.
* @return {@true} if the underlying setting is updated.
*/ */
public abstract void setChecked(boolean isChecked); public abstract boolean setChecked(boolean isChecked);
@Override @Override
public final void updateState(Preference preference) { public final void updateState(Preference preference) {
@@ -50,8 +51,6 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle
@Override @Override
public final boolean onPreferenceChange(Preference preference, Object newValue) { public final boolean onPreferenceChange(Preference preference, Object newValue) {
boolean auto = (Boolean) newValue; return setChecked((Boolean) newValue);
setChecked(auto);
return true;
} }
} }

View File

@@ -45,9 +45,10 @@ public class AutoBrightnessPreferenceController extends TogglePreferenceControll
} }
@Override @Override
public void setChecked(boolean isChecked) { public boolean setChecked(boolean isChecked) {
Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY, Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
isChecked ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE); isChecked ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : DEFAULT_VALUE);
return true;
} }
@Override @Override

View File

@@ -974,6 +974,10 @@ public class FingerprintSettings extends SubSettings {
} }
} }
/**
* @deprecated in favor of new SecuritySettings.
*/
@Deprecated
public static Preference getFingerprintPreferenceForUser(Context context, final int userId) { public static Preference getFingerprintPreferenceForUser(Context context, final int userId) {
final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context); final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
if (fpm == null || !fpm.isHardwareDetected()) { if (fpm == null || !fpm.isHardwareDetected()) {

View File

@@ -36,6 +36,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -78,7 +79,9 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
mProfileChallengeUserId = Utils.getManagedProfileId( mProfileChallengeUserId = Utils.getManagedProfileId(
UserManager.get(context), UserHandle.myUserId()); UserManager.get(context), UserHandle.myUserId());
final LockPatternUtils utils = new LockPatternUtils(context); final LockPatternUtils utils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mSecure = utils.isSecure(UserHandle.myUserId()); mSecure = utils.isSecure(UserHandle.myUserId());
mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL) mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL)
&& (utils.isSecure(mProfileChallengeUserId) && (utils.isSecure(mProfileChallengeUserId)
@@ -278,10 +281,14 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
} }
} }
public int getSummaryResource() { public static int getSummaryResource(Context context) {
final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId()); final boolean enabled = getLockscreenNotificationsEnabled(context, UserHandle.myUserId());
final boolean allowPrivate = !mSecure final boolean secure = FeatureFactory.getFactory(context)
|| getLockscreenAllowPrivateNotifications(UserHandle.myUserId()); .getSecurityFeatureProvider()
.getLockPatternUtils(context)
.isSecure(UserHandle.myUserId());
final boolean allowPrivate = !secure
|| getLockscreenAllowPrivateNotifications(context, UserHandle.myUserId());
return !enabled ? R.string.lock_screen_notifications_summary_disable : return !enabled ? R.string.lock_screen_notifications_summary_disable :
allowPrivate ? R.string.lock_screen_notifications_summary_show : allowPrivate ? R.string.lock_screen_notifications_summary_show :
R.string.lock_screen_notifications_summary_hide; R.string.lock_screen_notifications_summary_hide;
@@ -291,7 +298,7 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
if (mLockscreen == null) { if (mLockscreen == null) {
return; return;
} }
mLockscreenSelectedValue = getSummaryResource(); mLockscreenSelectedValue = getSummaryResource(mContext);
mLockscreen.setSummary("%s"); mLockscreen.setSummary("%s");
mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue)); mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue));
} }
@@ -303,9 +310,9 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
if (mLockscreenProfile == null) { if (mLockscreenProfile == null) {
return; return;
} }
final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId); final boolean enabled = getLockscreenNotificationsEnabled(mContext,mProfileChallengeUserId);
final boolean allowPrivate = !mSecureProfile final boolean allowPrivate = !mSecureProfile
|| getLockscreenAllowPrivateNotifications(mProfileChallengeUserId); || getLockscreenAllowPrivateNotifications(mContext, mProfileChallengeUserId);
mLockscreenProfile.setSummary("%s"); mLockscreenProfile.setSummary("%s");
mLockscreenSelectedValueProfile = !enabled mLockscreenSelectedValueProfile = !enabled
? R.string.lock_screen_notifications_summary_disable_profile ? R.string.lock_screen_notifications_summary_disable_profile
@@ -314,13 +321,13 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile)); mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile));
} }
private boolean getLockscreenNotificationsEnabled(int userId) { private static boolean getLockscreenNotificationsEnabled(Context context, int userId) {
return Settings.Secure.getIntForUser(mContext.getContentResolver(), return Settings.Secure.getIntForUser(context.getContentResolver(),
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0; Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0;
} }
private boolean getLockscreenAllowPrivateNotifications(int userId) { private static boolean getLockscreenAllowPrivateNotifications(Context context, int userId) {
return Settings.Secure.getIntForUser(mContext.getContentResolver(), return Settings.Secure.getIntForUser(context.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0; Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0;
} }

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import static com.android.settings.security
.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.widget.GearPreference;
public class ChangeProfileScreenLockPreferenceController extends
ChangeScreenLockPreferenceController {
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
public ChangeProfileScreenLockPreferenceController(Context context,
SecuritySettingsV2 host) {
super(context, host);
}
@Override
public void onGearClick(GearPreference p) {
}
@Override
public boolean isAvailable() {
if (mProfileChallengeUserId == UserHandle.USER_NULL ||
!mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
return false;
}
if (!mLockPatternUtils.isSecure(mProfileChallengeUserId)) {
return true;
}
switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
return true;
}
return false;
}
@Override
public String getPreferenceKey() {
return KEY_UNLOCK_SET_OR_CHANGE_PROFILE;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
return false;
}
final Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
return true;
}
@Override
public void updateState(Preference preference) {
updateSummary(preference, mProfileChallengeUserId);
if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
final String summary = mContext.getString(
R.string.lock_settings_profile_unified_summary);
mPreference.setSummary(summary);
mPreference.setEnabled(false);
} else {
// PO may disallow to change profile password, and the profile's password is
// separated from screen lock password. Disable profile specific "Screen lock" menu.
disableIfPasswordQualityManaged(mProfileChallengeUserId);
}
}
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import static com.android.settings.security.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.widget.GearPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
public class ChangeScreenLockPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, GearPreference.OnGearClickListener {
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
protected final DevicePolicyManager mDPM;
protected final SecuritySettingsV2 mHost;
protected final UserManager mUm;
protected final LockPatternUtils mLockPatternUtils;
protected final int mUserId = UserHandle.myUserId();
protected final int mProfileChallengeUserId;
protected RestrictedPreference mPreference;
public ChangeScreenLockPreferenceController(Context context, SecuritySettingsV2 host) {
super(context);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mHost = host;
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public String getPreferenceKey() {
return KEY_UNLOCK_SET_OR_CHANGE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (RestrictedPreference) screen.findPreference(getPreferenceKey());
if (mPreference != null && mPreference instanceof GearPreference) {
((GearPreference) mPreference).setOnGearClickListener(this);
}
}
@Override
public void updateState(Preference preference) {
updateSummary(preference, mUserId);
disableIfPasswordQualityManaged(mUserId);
if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
// PO may disallow to change password for the profile, but screen lock and managed
// profile's lock is the same. Disable main "Screen lock" menu.
disableIfPasswordQualityManaged(mProfileChallengeUserId);
}
}
@Override
public void onGearClick(GearPreference p) {
if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
mHost.startFragment(mHost, ScreenLockSettings.class.getName(), 0, 0, null);
}
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return super.handlePreferenceTreeClick(preference);
}
// TODO(b/35930129): Remove once existing password can be passed into vold directly.
// Currently we need this logic to ensure that the QUIET_MODE is off for any work
// profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
// able to complete the operation due to the lack of (old) encryption key.
if (mProfileChallengeUserId != UserHandle.USER_NULL
&& !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
&& StorageManager.isFileEncryptedNativeOnly()) {
if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
return false;
}
}
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
return true;
}
protected void updateSummary(Preference preference, int userId) {
if (!mLockPatternUtils.isSecure(userId)) {
if (userId == mProfileChallengeUserId
|| mLockPatternUtils.isLockScreenDisabled(userId)) {
preference.setSummary(R.string.unlock_set_unlock_mode_off);
} else {
preference.setSummary(R.string.unlock_set_unlock_mode_none);
}
} else {
switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
preference.setSummary(R.string.unlock_set_unlock_mode_pattern);
break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
preference.setSummary(R.string.unlock_set_unlock_mode_pin);
break;
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
preference.setSummary(R.string.unlock_set_unlock_mode_password);
break;
}
}
}
/**
* Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
* The preference must be a RestrictedPreference.
* <p/>
* DO or PO installed in the user may disallow to change password.
*/
void disableIfPasswordQualityManaged(int userId) {
final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils
.checkIfPasswordQualityIsSet(mContext, userId);
final DevicePolicyManager dpm = (DevicePolicyManager) mContext
.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (admin != null && dpm.getPasswordQuality(admin.component, userId)
== DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
mPreference.setDisabledByAdmin(admin);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import android.content.Context;
import android.os.UserHandle;
public class FingerprintProfileStatusPreferenceController
extends FingerprintStatusPreferenceController {
public static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings_profile";
public FingerprintProfileStatusPreferenceController(Context context) {
super(context, KEY_FINGERPRINT_SETTINGS);
}
@Override
protected boolean isUserSupported() {
return mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId);
}
@Override
protected int getUserId() {
return mProfileChallengeUserId;
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import android.content.Context;
import android.content.Intent;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.fingerprint.FingerprintEnrollIntroduction;
import com.android.settings.fingerprint.FingerprintSettings;
import com.android.settings.overlay.FeatureFactory;
import java.util.List;
public class FingerprintStatusPreferenceController extends BasePreferenceController {
private static final String KEY_FINGERPRINT_SETTINGS = "fingerprint_settings";
protected final FingerprintManager mFingerprintManager;
protected final UserManager mUm;
protected final LockPatternUtils mLockPatternUtils;
protected final int mUserId = UserHandle.myUserId();
protected final int mProfileChallengeUserId;
public FingerprintStatusPreferenceController(Context context) {
this(context, KEY_FINGERPRINT_SETTINGS);
}
public FingerprintStatusPreferenceController(Context context, String key) {
super(context, key);
mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
}
@Override
public int getAvailabilityStatus() {
if (mFingerprintManager == null || !mFingerprintManager.isHardwareDetected()) {
return DISABLED_UNSUPPORTED;
}
if (isUserSupported()) {
return AVAILABLE;
} else {
return DISABLED_FOR_USER;
}
}
@Override
public void updateState(Preference preference) {
if (!isAvailable()) {
if (preference != null) {
preference.setVisible(false);
}
return;
} else {
preference.setVisible(true);
}
final int userId = getUserId();
final List<Fingerprint> items = mFingerprintManager.getEnrolledFingerprints(userId);
final int fingerprintCount = items != null ? items.size() : 0;
final String clazz;
if (fingerprintCount > 0) {
preference.setSummary(mContext.getResources().getQuantityString(
R.plurals.security_settings_fingerprint_preference_summary,
fingerprintCount, fingerprintCount));
clazz = FingerprintSettings.class.getName();
} else {
preference.setSummary(
R.string.security_settings_fingerprint_preference_summary_none);
clazz = FingerprintEnrollIntroduction.class.getName();
}
preference.setOnPreferenceClickListener(target -> {
final Context context = target.getContext();
final UserManager userManager = UserManager.get(context);
if (Utils.startQuietModeDialogIfNecessary(context, userManager,
userId)) {
return false;
}
Intent intent = new Intent();
intent.setClassName("com.android.settings", clazz);
intent.putExtra(Intent.EXTRA_USER_ID, userId);
context.startActivity(intent);
return true;
});
}
protected int getUserId() {
return mUserId;
}
protected boolean isUserSupported() {
return true;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import android.content.Context;
import android.os.UserHandle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.overlay.FeatureFactory;
public class LockScreenPreferenceController extends BasePreferenceController {
static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
private static final int MY_USER_ID = UserHandle.myUserId();
private final LockPatternUtils mLockPatternUtils;
public LockScreenPreferenceController(Context context) {
super(context, KEY_LOCKSCREEN_PREFERENCES);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider().getLockPatternUtils(context);
}
@Override
public int getAvailabilityStatus() {
if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
return mLockPatternUtils.isLockScreenDisabled(MY_USER_ID)
? DISABLED_FOR_USER : AVAILABLE;
} else {
return mLockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)
== PASSWORD_QUALITY_UNSPECIFIED
? DISABLED_FOR_USER : AVAILABLE;
}
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final Preference lockscreenPreferences = screen.findPreference(getPreferenceKey());
if (lockscreenPreferences != null) {
lockscreenPreferences.setSummary(
LockScreenNotificationPreferenceController.getSummaryResource(mContext));
}
}
}

View File

@@ -0,0 +1,218 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import static com.android.settings.security
.SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE;
import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
import static com.android.settings.security.SecuritySettingsV2.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
import static com.android.settings.security.SecuritySettingsV2.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
public class LockUnificationPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
private static final String KEY_UNIFICATION = "unification";
private static final int MY_USER_ID = UserHandle.myUserId();
private final UserManager mUm;
private final LockPatternUtils mLockPatternUtils;
private final int mProfileChallengeUserId;
private final SecuritySettingsV2 mHost;
private RestrictedSwitchPreference mUnifyProfile;
private String mCurrentDevicePassword;
private String mCurrentProfilePassword;
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mUnifyProfile = (RestrictedSwitchPreference) screen.findPreference(KEY_UNIFICATION);
}
public LockUnificationPreferenceController(Context context, SecuritySettingsV2 host) {
super(context);
mHost = host;
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
}
@Override
public boolean isAvailable() {
final boolean allowSeparateProfileChallenge =
mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(
mProfileChallengeUserId);
return allowSeparateProfileChallenge;
}
@Override
public String getPreferenceKey() {
return KEY_UNIFICATION;
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
return false;
}
if ((Boolean) value) {
final boolean compliantForDevice =
(mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
mProfileChallengeUserId));
UnificationConfirmationDialog dialog =
UnificationConfirmationDialog.newInstance(compliantForDevice);
dialog.show(mHost);
} else {
final String title = mContext.getString(R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity(
UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST,
title, true /* returnCredentials */, MY_USER_ID)) {
ununifyLocks();
}
}
return true;
}
@Override
public void updateState(Preference preference) {
if (mUnifyProfile != null) {
final boolean separate =
mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
mUnifyProfile.setChecked(!separate);
if (separate) {
mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
mContext, UserManager.DISALLOW_UNIFIED_PASSWORD,
mProfileChallengeUserId));
}
}
}
public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
ununifyLocks();
return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword =
data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
launchConfirmProfileLockForUnification();
return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentProfilePassword =
data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
unifyLocks();
return true;
}
return false;
}
private void ununifyLocks() {
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
mHost.startFragment(mHost,
ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
}
void launchConfirmDeviceLockForUnification() {
final String title = mContext.getString(
R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
launchConfirmProfileLockForUnification();
}
}
private void launchConfirmProfileLockForUnification() {
final String title = mContext.getString(
R.string.unlock_set_unlock_launch_picker_title_profile);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
unifyLocks();
// TODO: update relevant prefs.
// createPreferenceHierarchy();
}
}
private void unifyLocks() {
int profileQuality =
mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.stringToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID);
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword,
profileQuality, MY_USER_ID);
}
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
mCurrentProfilePassword);
final boolean profilePatternVisibility =
mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
mCurrentDevicePassword = null;
mCurrentProfilePassword = null;
}
void unifyUncompliantLocks() {
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
mCurrentProfilePassword);
mHost.startFragment(mHost, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title,
SecuritySettingsV2.SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
}
}

View File

@@ -161,7 +161,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
private LocationPreferenceController mLocationcontroller; private LocationPreferenceController mLocationcontroller;
private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController; private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController; private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
private LockScreenNotificationPreferenceController mLockScreenNotificationPreferenceController;
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
@@ -208,8 +207,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
= new ManageDeviceAdminPreferenceController(activity); = new ManageDeviceAdminPreferenceController(activity);
mEnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController
= new EnterprisePrivacyPreferenceController(activity); = new EnterprisePrivacyPreferenceController(activity);
mLockScreenNotificationPreferenceController
= new LockScreenNotificationPreferenceController(activity);
} }
private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils, private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
@@ -430,7 +427,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES); final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
if (lockscreenPreferences != null) { if (lockscreenPreferences != null) {
lockscreenPreferences.setSummary( lockscreenPreferences.setSummary(
mLockScreenNotificationPreferenceController.getSummaryResource()); LockScreenNotificationPreferenceController.getSummaryResource(getContext()));
} }
} }

View File

@@ -1,25 +1,16 @@
package com.android.settings.security; package com.android.settings.security;
import static com.android.settings.security.EncryptionStatusPreferenceController import static com.android.settings.security.EncryptionStatusPreferenceController.PREF_KEY_ENCRYPTION_SECURITY_PAGE;
.PREF_KEY_ENCRYPTION_SECURITY_PAGE;
import android.app.Activity; import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.SearchIndexableResource; import android.provider.SearchIndexableResource;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
@@ -30,96 +21,62 @@ import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader; import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.enterprise.EnterprisePrivacyPreferenceController; import com.android.settings.enterprise.EnterprisePrivacyPreferenceController;
import com.android.settings.enterprise.ManageDeviceAdminPreferenceController; import com.android.settings.enterprise.ManageDeviceAdminPreferenceController;
import com.android.settings.fingerprint.FingerprintSettings;
import com.android.settings.location.LocationPreferenceController; import com.android.settings.location.LocationPreferenceController;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ManagedLockPasswordProvider;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.security.trustagent.ManageTrustAgentsPreferenceController; import com.android.settings.security.trustagent.ManageTrustAgentsPreferenceController;
import com.android.settings.security.trustagent.TrustAgentListPreferenceController; import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
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.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.drawer.CategoryKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class SecuritySettingsV2 extends DashboardFragment public class SecuritySettingsV2 extends DashboardFragment {
implements Preference.OnPreferenceChangeListener,
GearPreference.OnGearClickListener {
private static final String TAG = "SecuritySettingsV2"; private static final String TAG = "SecuritySettingsV2";
// Lock Settings public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
private static final String KEY_SECURITY_CATEGORY = "security_category";
private static final String KEY_UNIFICATION = "unification";
@VisibleForTesting
static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
private static final String KEY_ENCRYPTION_AND_CREDENTIALS = "encryption_and_credential";
private static final String KEY_LOCATION_SCANNING = "location_scanning";
private static final String KEY_LOCATION = "location";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
public static final int CHANGE_TRUST_AGENT_SETTINGS = 126; public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127; public static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
private static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128; public static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
private static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129; public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
private static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130; public static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
private static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
// Security status // Security status
private static final String KEY_SECURITY_STATUS = "security_status"; private static final String KEY_SECURITY_STATUS = "security_status";
private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_"; private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_";
// Device management settings
private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
private static final String KEY_MANAGE_DEVICE_ADMIN = "manage_device_admin";
// These switch preferences need special handling since they're not all stored in Settings.
private static final String SWITCH_PREFERENCE_KEYS[] = {
KEY_UNIFICATION, KEY_VISIBLE_PATTERN_PROFILE
};
private static final int MY_USER_ID = UserHandle.myUserId(); private static final int MY_USER_ID = UserHandle.myUserId();
private DashboardFeatureProvider mDashboardFeatureProvider; private DashboardFeatureProvider mDashboardFeatureProvider;
private DevicePolicyManager mDPM;
private SecurityFeatureProvider mSecurityFeatureProvider; private SecurityFeatureProvider mSecurityFeatureProvider;
private UserManager mUm; private UserManager mUm;
private ChooseLockSettingsHelper mChooseLockSettingsHelper; private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private ManagedLockPasswordProvider mManagedPasswordProvider;
private SwitchPreference mVisiblePatternProfile;
private RestrictedSwitchPreference mUnifyProfile;
private int mProfileChallengeUserId; private int mProfileChallengeUserId;
private String mCurrentDevicePassword;
private String mCurrentProfilePassword;
private LocationPreferenceController mLocationController; private LocationPreferenceController mLocationController;
private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController; private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController; private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
private EncryptionStatusPreferenceController mEncryptionStatusPreferenceController; private EncryptionStatusPreferenceController mEncryptionStatusPreferenceController;
private LockScreenNotificationPreferenceController mLockScreenNotificationPreferenceController;
private ManageTrustAgentsPreferenceController mManageTrustAgentsPreferenceController; private ManageTrustAgentsPreferenceController mManageTrustAgentsPreferenceController;
private ScreenPinningPreferenceController mScreenPinningPreferenceController; private ScreenPinningPreferenceController mScreenPinningPreferenceController;
private SimLockPreferenceController mSimLockPreferenceController; private SimLockPreferenceController mSimLockPreferenceController;
private ShowPasswordPreferenceController mShowPasswordPreferenceController; private ShowPasswordPreferenceController mShowPasswordPreferenceController;
private TrustAgentListPreferenceController mTrustAgentListPreferenceController; private TrustAgentListPreferenceController mTrustAgentListPreferenceController;
private LockScreenPreferenceController mLockScreenPreferenceController;
private ChangeScreenLockPreferenceController mChangeScreenLockPreferenceController;
private ChangeProfileScreenLockPreferenceController
mChangeProfileScreenLockPreferenceController;
private LockUnificationPreferenceController mLockUnificationPreferenceController;
private VisiblePatternProfilePreferenceController mVisiblePatternProfilePreferenceController;
private FingerprintStatusPreferenceController mFingerprintStatusPreferenceController;
private FingerprintProfileStatusPreferenceController
mFingerprintProfileStatusPreferenceController;
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
@@ -132,8 +89,6 @@ public class SecuritySettingsV2 extends DashboardFragment
mSecurityFeatureProvider = FeatureFactory.getFactory(context).getSecurityFeatureProvider(); mSecurityFeatureProvider = FeatureFactory.getFactory(context).getSecurityFeatureProvider();
mLocationController = new LocationPreferenceController(context, getLifecycle()); mLocationController = new LocationPreferenceController(context, getLifecycle());
mLockPatternUtils = mSecurityFeatureProvider.getLockPatternUtils(context); mLockPatternUtils = mSecurityFeatureProvider.getLockPatternUtils(context);
mManagedPasswordProvider = ManagedLockPasswordProvider.get(context, MY_USER_ID);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mUm = UserManager.get(context); mUm = UserManager.get(context);
mDashboardFeatureProvider = FeatureFactory.getFactory(context) mDashboardFeatureProvider = FeatureFactory.getFactory(context)
.getDashboardFeatureProvider(context); .getDashboardFeatureProvider(context);
@@ -151,14 +106,18 @@ public class SecuritySettingsV2 extends DashboardFragment
return TAG; return TAG;
} }
@Override
public int getHelpResource() {
return R.string.help_url_security;
}
@Override @Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) { protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
mManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController
= new ManageDeviceAdminPreferenceController(context); = new ManageDeviceAdminPreferenceController(context);
mEnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController
= new EnterprisePrivacyPreferenceController(context); = new EnterprisePrivacyPreferenceController(context);
mLockScreenNotificationPreferenceController
= new LockScreenNotificationPreferenceController(context);
mManageTrustAgentsPreferenceController = new ManageTrustAgentsPreferenceController(context); mManageTrustAgentsPreferenceController = new ManageTrustAgentsPreferenceController(context);
mScreenPinningPreferenceController = new ScreenPinningPreferenceController(context); mScreenPinningPreferenceController = new ScreenPinningPreferenceController(context);
mSimLockPreferenceController = new SimLockPreferenceController(context); mSimLockPreferenceController = new SimLockPreferenceController(context);
@@ -167,46 +126,21 @@ public class SecuritySettingsV2 extends DashboardFragment
context, PREF_KEY_ENCRYPTION_SECURITY_PAGE); context, PREF_KEY_ENCRYPTION_SECURITY_PAGE);
mTrustAgentListPreferenceController = new TrustAgentListPreferenceController(getActivity(), mTrustAgentListPreferenceController = new TrustAgentListPreferenceController(getActivity(),
this /* host */, getLifecycle()); this /* host */, getLifecycle());
mLockScreenPreferenceController = new LockScreenPreferenceController(context);
mChangeScreenLockPreferenceController = new ChangeScreenLockPreferenceController(context,
this /* host */);
mChangeProfileScreenLockPreferenceController =
new ChangeProfileScreenLockPreferenceController(context, this /* host */);
mLockUnificationPreferenceController = new LockUnificationPreferenceController(context,
this /* host */);
mVisiblePatternProfilePreferenceController =
new VisiblePatternProfilePreferenceController(context);
mFingerprintStatusPreferenceController = new FingerprintStatusPreferenceController(context);
mFingerprintProfileStatusPreferenceController =
new FingerprintProfileStatusPreferenceController(context);
return null; return null;
} }
private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
ManagedLockPasswordProvider managedPasswordProvider, int userId) {
final boolean isMyUser = userId == MY_USER_ID;
int resid = 0;
if (!lockPatternUtils.isSecure(userId)) {
if (!isMyUser) {
resid = R.xml.security_settings_lockscreen_profile;
} else if (lockPatternUtils.isLockScreenDisabled(userId)) {
resid = R.xml.security_settings_lockscreen;
} else {
resid = R.xml.security_settings_chooser;
}
} else {
switch (lockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
resid = isMyUser ? R.xml.security_settings_pattern
: R.xml.security_settings_pattern_profile;
break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
resid = isMyUser ? R.xml.security_settings_pin
: R.xml.security_settings_pin_profile;
break;
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
resid = isMyUser ? R.xml.security_settings_password
: R.xml.security_settings_password_profile;
break;
case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
resid = managedPasswordProvider.getResIdForLockUnlockScreen(!isMyUser);
break;
}
}
return resid;
}
/** /**
* Important! * Important!
* *
@@ -214,65 +148,15 @@ public class SecuritySettingsV2 extends DashboardFragment
* logic or adding/removing preferences here. * logic or adding/removing preferences here.
*/ */
private PreferenceScreen createPreferenceHierarchy() { private PreferenceScreen createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen(); final PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
addPreferencesFromResource(R.xml.security_settings_v2);
root = getPreferenceScreen();
mTrustAgentListPreferenceController.displayPreference(root); mTrustAgentListPreferenceController.displayPreference(root);
mLockScreenPreferenceController.displayPreference(root);
// Add options for lock/unlock screen mChangeScreenLockPreferenceController.displayPreference(root);
final int resid = getResIdForLockUnlockScreen(mLockPatternUtils, mChangeProfileScreenLockPreferenceController.displayPreference(root);
mManagedPasswordProvider, MY_USER_ID); mLockUnificationPreferenceController.displayPreference(root);
addPreferencesFromResource(resid); mVisiblePatternProfilePreferenceController.displayPreference(root);
mFingerprintStatusPreferenceController.displayPreference(root);
// DO or PO installed in the user may disallow to change password. mFingerprintProfileStatusPreferenceController.displayPreference(root);
disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, MY_USER_ID);
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
if (mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
addPreferencesFromResource(R.xml.security_settings_profile);
addPreferencesFromResource(R.xml.security_settings_unification);
final int profileResid = getResIdForLockUnlockScreen(mLockPatternUtils,
mManagedPasswordProvider, mProfileChallengeUserId);
addPreferencesFromResource(profileResid);
maybeAddFingerprintPreference(root, mProfileChallengeUserId);
if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
final Preference lockPreference =
root.findPreference(KEY_UNLOCK_SET_OR_CHANGE_PROFILE);
final String summary = getContext().getString(
R.string.lock_settings_profile_unified_summary);
lockPreference.setSummary(summary);
lockPreference.setEnabled(false);
// PO may disallow to change password for the profile, but screen lock and managed
// profile's lock is the same. Disable main "Screen lock" menu.
disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, mProfileChallengeUserId);
} else {
// PO may disallow to change profile password, and the profile's password is
// separated from screen lock password. Disable profile specific "Screen lock" menu.
disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE_PROFILE,
mProfileChallengeUserId);
}
}
Preference unlockSetOrChange = findPreference(KEY_UNLOCK_SET_OR_CHANGE);
if (unlockSetOrChange instanceof GearPreference) {
((GearPreference) unlockSetOrChange).setOnGearClickListener(this);
}
// Fingerprint and trust agents
PreferenceGroup securityCategory = (PreferenceGroup)
root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null) {
maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
setLockscreenPreferencesSummary(securityCategory);
}
mVisiblePatternProfile =
(SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION);
mSimLockPreferenceController.displayPreference(root); mSimLockPreferenceController.displayPreference(root);
mScreenPinningPreferenceController.displayPreference(root); mScreenPinningPreferenceController.displayPreference(root);
@@ -280,45 +164,40 @@ public class SecuritySettingsV2 extends DashboardFragment
// Advanced Security features // Advanced Security features
mManageTrustAgentsPreferenceController.displayPreference(root); mManageTrustAgentsPreferenceController.displayPreference(root);
PreferenceGroup securityStatusPreferenceGroup = // PreferenceGroup securityStatusPreferenceGroup =
(PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS); // (PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS);
final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory( // final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
getActivity(), getPrefContext(), getMetricsCategory(), // getActivity(), getPrefContext(), getMetricsCategory(),
CategoryKey.CATEGORY_SECURITY); // CategoryKey.CATEGORY_SECURITY);
int numSecurityStatusPrefs = 0; // int numSecurityStatusPrefs = 0;
if (tilePrefs != null && !tilePrefs.isEmpty()) { // if (tilePrefs != null && !tilePrefs.isEmpty()) {
for (Preference preference : tilePrefs) { // for (Preference preference : tilePrefs) {
if (!TextUtils.isEmpty(preference.getKey()) // if (!TextUtils.isEmpty(preference.getKey())
&& preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) { // && preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) {
// Injected security status settings are placed under the Security status // // Injected security status settings are placed under the Security status
// category. // // category.
securityStatusPreferenceGroup.addPreference(preference); // securityStatusPreferenceGroup.addPreference(preference);
numSecurityStatusPrefs++; // numSecurityStatusPrefs++;
} else { // } else {
// Other injected settings are placed under the Security preference screen. // // Other injected settings are placed under the Security preference screen.
root.addPreference(preference); // root.addPreference(preference);
} // }
} // }
} // }
//
if (numSecurityStatusPrefs == 0) { // if (numSecurityStatusPrefs == 0) {
root.removePreference(securityStatusPreferenceGroup); // root.removePreference(securityStatusPreferenceGroup);
} else if (numSecurityStatusPrefs > 0) { // } else if (numSecurityStatusPrefs > 0) {
// Update preference data with tile data. Security feature provider only updates the // // Update preference data with tile data. Security feature provider only updates the
// data if it actually needs to be changed. // // data if it actually needs to be changed.
mSecurityFeatureProvider.updatePreferences(getActivity(), root, // mSecurityFeatureProvider.updatePreferences(getActivity(), root,
mDashboardFeatureProvider.getTilesForCategory( // mDashboardFeatureProvider.getTilesForCategory(
CategoryKey.CATEGORY_SECURITY)); // CategoryKey.CATEGORY_SECURITY));
} // }
for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
if (pref != null) pref.setOnPreferenceChangeListener(this);
}
mLocationController.displayPreference(root); mLocationController.displayPreference(root);
mManageDeviceAdminPreferenceController.updateState( mManageDeviceAdminPreferenceController.updateState(
root.findPreference(KEY_MANAGE_DEVICE_ADMIN)); root.findPreference(mManageDeviceAdminPreferenceController.getPreferenceKey()));
mEnterprisePrivacyPreferenceController.displayPreference(root); mEnterprisePrivacyPreferenceController.displayPreference(root);
final Preference enterprisePrivacyPreference = root.findPreference( final Preference enterprisePrivacyPreference = root.findPreference(
mEnterprisePrivacyPreferenceController.getPreferenceKey()); mEnterprisePrivacyPreferenceController.getPreferenceKey());
@@ -327,47 +206,6 @@ public class SecuritySettingsV2 extends DashboardFragment
return root; return root;
} }
@VisibleForTesting
void setLockscreenPreferencesSummary(PreferenceGroup group) {
final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
if (lockscreenPreferences != null) {
lockscreenPreferences.setSummary(
mLockScreenNotificationPreferenceController.getSummaryResource());
}
}
/*
* Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
* The preference must be a RestrictedPreference.
*/
private void disableIfPasswordQualityManaged(String preferenceKey, int userId) {
final RestrictedLockUtils.EnforcedAdmin admin =
RestrictedLockUtils.checkIfPasswordQualityIsSet(
getActivity(), userId);
if (admin != null && mDPM.getPasswordQuality(admin.component, userId) ==
DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
final RestrictedPreference pref =
(RestrictedPreference) getPreferenceScreen().findPreference(preferenceKey);
pref.setDisabledByAdmin(admin);
}
}
private void maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId) {
Preference fingerprintPreference =
FingerprintSettings.getFingerprintPreferenceForUser(
securityCategory.getContext(), userId);
if (fingerprintPreference != null) {
securityCategory.addPreference(fingerprintPreference);
}
}
@Override
public void onGearClick(GearPreference p) {
if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
startFragment(this, ScreenLockSettings.class.getName(), 0, 0, null);
}
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
@@ -376,18 +214,40 @@ public class SecuritySettingsV2 extends DashboardFragment
// depend on others... // depend on others...
createPreferenceHierarchy(); createPreferenceHierarchy();
if (mVisiblePatternProfile != null) { final Preference visiblePatternProfilePref = getPreferenceScreen().findPreference(
mVisiblePatternProfile.setChecked(mLockPatternUtils.isVisiblePatternEnabled( mVisiblePatternProfilePreferenceController.getPreferenceKey());
mProfileChallengeUserId)); if (visiblePatternProfilePref != null) {
visiblePatternProfilePref
.setOnPreferenceChangeListener(mVisiblePatternProfilePreferenceController);
mVisiblePatternProfilePreferenceController.updateState(visiblePatternProfilePref);
} }
updateUnificationPreference();
final Preference showPasswordPref = getPreferenceScreen().findPreference( final Preference showPasswordPref = getPreferenceScreen().findPreference(
mShowPasswordPreferenceController.getPreferenceKey()); mShowPasswordPreferenceController.getPreferenceKey());
showPasswordPref.setOnPreferenceChangeListener(mShowPasswordPreferenceController); showPasswordPref.setOnPreferenceChangeListener(mShowPasswordPreferenceController);
mShowPasswordPreferenceController.updateState(showPasswordPref); mShowPasswordPreferenceController.updateState(showPasswordPref);
final Preference lockUnificationPref = getPreferenceScreen().findPreference(
mLockUnificationPreferenceController.getPreferenceKey());
lockUnificationPref.setOnPreferenceChangeListener(mLockUnificationPreferenceController);
mLockUnificationPreferenceController.updateState(lockUnificationPref);
final Preference changeDeviceLockPref = getPreferenceScreen().findPreference(
mChangeScreenLockPreferenceController.getPreferenceKey());
mChangeScreenLockPreferenceController.updateState(changeDeviceLockPref);
mFingerprintStatusPreferenceController.updateState(
getPreferenceScreen().findPreference(
mFingerprintStatusPreferenceController.getPreferenceKey()));
mFingerprintProfileStatusPreferenceController.updateState(
getPreferenceScreen().findPreference(
mFingerprintProfileStatusPreferenceController.getPreferenceKey()));
final Preference changeProfileLockPref = getPreferenceScreen().findPreference(
mChangeProfileScreenLockPreferenceController.getPreferenceKey());
mChangeProfileScreenLockPreferenceController.updateState(changeProfileLockPref);
final Preference encryptionStatusPref = getPreferenceScreen().findPreference( final Preference encryptionStatusPref = getPreferenceScreen().findPreference(
mEncryptionStatusPreferenceController.getPreferenceKey()); mEncryptionStatusPreferenceController.getPreferenceKey());
mEncryptionStatusPreferenceController.updateState(encryptionStatusPref); mEncryptionStatusPreferenceController.updateState(encryptionStatusPref);
@@ -395,57 +255,21 @@ public class SecuritySettingsV2 extends DashboardFragment
mLocationController.updateSummary(); mLocationController.updateSummary();
} }
@VisibleForTesting
void updateUnificationPreference() {
if (mUnifyProfile != null) {
final boolean separate =
mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
mUnifyProfile.setChecked(!separate);
if (separate) {
mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD,
mProfileChallengeUserId));
}
}
}
@Override @Override
public boolean onPreferenceTreeClick(Preference preference) { public boolean onPreferenceTreeClick(Preference preference) {
if (mTrustAgentListPreferenceController.handlePreferenceTreeClick(preference)) { if (mTrustAgentListPreferenceController.handlePreferenceTreeClick(preference)) {
return true; return true;
} }
final String key = preference.getKey(); if (mChangeScreenLockPreferenceController.handlePreferenceTreeClick(preference)) {
if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) { return true;
// TODO(b/35930129): Remove once existing password can be passed into vold directly.
// Currently we need this logic to ensure that the QUIET_MODE is off for any work
// profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
// able to complete the operation due to the lack of (old) encryption key.
if (mProfileChallengeUserId != UserHandle.USER_NULL
&& !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
&& StorageManager.isFileEncryptedNativeOnly()) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
} }
if (mChangeProfileScreenLockPreferenceController.handlePreferenceTreeClick(preference)) {
return true;
} }
startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
} else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
} else {
// If we didn't handle it, let preferences handle it. // If we didn't handle it, let preferences handle it.
return super.onPreferenceTreeClick(preference); return super.onPreferenceTreeClick(preference);
} }
return true;
}
/** /**
* see confirmPatternThenDisableAndClear * see confirmPatternThenDisableAndClear
@@ -453,139 +277,34 @@ public class SecuritySettingsV2 extends DashboardFragment
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) { if (mTrustAgentListPreferenceController.handleActivityResult(requestCode, resultCode)) {
mTrustAgentListPreferenceController.handleActivityResult(resultCode);
return; return;
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST }
&& resultCode == Activity.RESULT_OK) { if (mLockUnificationPreferenceController.handleActivityResult(
mCurrentDevicePassword = requestCode, resultCode, data)) {
data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
launchConfirmProfileLockForUnification();
return;
} else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentProfilePassword =
data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
unifyLocks();
return;
} else if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
ununifyLocks();
return; return;
} }
createPreferenceHierarchy(); createPreferenceHierarchy();
} }
void launchConfirmDeviceLockForUnification() {
final String title = getActivity().getString(
R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
launchConfirmProfileLockForUnification();
}
}
private void launchConfirmProfileLockForUnification() {
final String title = getActivity().getString(
R.string.unlock_set_unlock_launch_picker_title_profile);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
unifyLocks();
createPreferenceHierarchy();
}
}
private void unifyLocks() {
int profileQuality =
mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.stringToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID);
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword,
profileQuality, MY_USER_ID);
}
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
mCurrentProfilePassword);
final boolean profilePatternVisibility =
mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
mCurrentDevicePassword = null;
mCurrentProfilePassword = null;
}
void unifyUncompliantLocks() {
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
mCurrentProfilePassword);
startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
}
private void ununifyLocks() {
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
startFragment(this,
ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
boolean result = true;
final String key = preference.getKey();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
} else if (KEY_UNIFICATION.equals(key)) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
if ((Boolean) value) {
final boolean compliantForDevice =
(mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
mProfileChallengeUserId));
UnificationConfirmationDialog dialog =
UnificationConfirmationDialog.newIntance(compliantForDevice);
dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
} else {
final String title = getActivity().getString(
R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
ununifyLocks();
}
}
}
return result;
}
@Override
public int getHelpResource() {
return R.string.help_url_security;
}
/** /**
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()" * For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/ */
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new SecuritySearchIndexProvider(); new SecuritySearchIndexProvider();
void launchConfirmDeviceLockForUnification() {
mLockUnificationPreferenceController.launchConfirmDeviceLockForUnification();
}
void unifyUncompliantLocks() {
mLockUnificationPreferenceController.unifyUncompliantLocks();
}
void updateUnificationPreference() {
mLockUnificationPreferenceController.updateState(null);
}
private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider { private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
// TODO (b/68001777) Refactor indexing to include all XML and block other settings. // TODO (b/68001777) Refactor indexing to include all XML and block other settings.
@@ -594,123 +313,11 @@ public class SecuritySettingsV2 extends DashboardFragment
public List<SearchIndexableResource> getXmlResourcesToIndex( public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) { Context context, boolean enabled) {
final List<SearchIndexableResource> index = new ArrayList<>(); final List<SearchIndexableResource> index = new ArrayList<>();
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
final ManagedLockPasswordProvider managedPasswordProvider =
ManagedLockPasswordProvider.get(context, MY_USER_ID);
final DevicePolicyManager dpm = (DevicePolicyManager)
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
final UserManager um = UserManager.get(context);
final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
// To add option for unlock screen, user's password must not be managed and
// must not be unified with managed profile, whose password is managed.
if (!isPasswordManaged(MY_USER_ID, context, dpm)
&& (profileUserId == UserHandle.USER_NULL
|| lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
|| !isPasswordManaged(profileUserId, context, dpm))) {
// Add options for lock/unlock screen
final int resId = getResIdForLockUnlockScreen(lockPatternUtils,
managedPasswordProvider, MY_USER_ID);
index.add(getSearchResource(context, resId));
}
if (profileUserId != UserHandle.USER_NULL
&& lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
&& !isPasswordManaged(profileUserId, context, dpm)) {
index.add(getSearchResource(context, getResIdForLockUnlockScreen(
lockPatternUtils, managedPasswordProvider, profileUserId)));
}
// Append the rest of the settings // Append the rest of the settings
index.add(getSearchResource(context, R.xml.security_settings_misc));
return index;
}
private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
final SearchIndexableResource sir = new SearchIndexableResource(context); final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = xmlResId; sir.xmlResId = R.xml.security_settings_v2;
return sir; index.add(sir);
} return index;
private boolean isPasswordManaged(int userId, Context context, DevicePolicyManager dpm) {
final RestrictedLockUtils.EnforcedAdmin admin =
RestrictedLockUtils.checkIfPasswordQualityIsSet(
context, userId);
return admin != null && dpm.getPasswordQuality(admin.component, userId) ==
DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
}
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
final Resources res = context.getResources();
final String screenTitle = res.getString(R.string.security_settings_title);
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = screenTitle;
data.key = "security_settings_screen";
data.screenTitle = screenTitle;
result.add(data);
final UserManager um = UserManager.get(context);
// Fingerprint
final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
if (fpm != null && fpm.isHardwareDetected()) {
// This catches the title which can be overloaded in an overlay
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.security_settings_fingerprint_preference_title);
data.key = "security_fingerprint";
data.screenTitle = screenTitle;
result.add(data);
// Fallback for when the above doesn't contain "fingerprint"
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.fingerprint_manage_category_title);
data.key = "security_managed_fingerprint";
data.screenTitle = screenTitle;
result.add(data);
}
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
if (profileUserId != UserHandle.USER_NULL
&& lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
if (lockPatternUtils.getKeyguardStoredPasswordQuality(profileUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& lockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
profileUserId)) {
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.lock_settings_profile_unification_title);
data.key = "security_use_one_lock";
data.screenTitle = screenTitle;
result.add(data);
}
}
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
new SimLockPreferenceController(context).updateNonIndexableKeys(keys);
if (!(new EnterprisePrivacyPreferenceController(context))
.isAvailable()) {
keys.add(KEY_ENTERPRISE_PRIVACY);
}
// Duplicate in special app access
keys.add(KEY_MANAGE_DEVICE_ADMIN);
// Duplicates between parent-child
keys.add(KEY_LOCATION);
keys.add(KEY_ENCRYPTION_AND_CREDENTIALS);
keys.add(KEY_LOCATION_SCANNING);
return keys;
} }
} }

View File

@@ -44,10 +44,11 @@ public class ShowPasswordPreferenceController extends TogglePreferenceController
} }
@Override @Override
public void setChecked(boolean isChecked) { public boolean setChecked(boolean isChecked) {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, Settings.System.putInt(mContext.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
isChecked ? 1 : 0); isChecked ? 1 : 0);
mLockPatternUtils.setVisiblePasswordEnabled(isChecked, MY_USER_ID); mLockPatternUtils.setVisiblePasswordEnabled(isChecked, MY_USER_ID);
return true;
} }
@Override @Override

View File

@@ -27,9 +27,11 @@ import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
public class UnificationConfirmationDialog extends InstrumentedDialogFragment { public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
private static final String EXTRA_COMPLIANT = "compliant"; private static final String EXTRA_COMPLIANT = "compliant";
public static UnificationConfirmationDialog newIntance(boolean compliant) { public static UnificationConfirmationDialog newInstance(boolean compliant) {
UnificationConfirmationDialog UnificationConfirmationDialog
dialog = new UnificationConfirmationDialog(); dialog = new UnificationConfirmationDialog();
Bundle args = new Bundle(); Bundle args = new Bundle();
@@ -38,11 +40,11 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
return dialog; return dialog;
} }
@Override public void show(SecuritySettingsV2 host) {
public void show(FragmentManager manager, String tag) { final FragmentManager manager = host.getChildFragmentManager();
if (manager.findFragmentByTag(tag) == null) { if (manager.findFragmentByTag(TAG_UNIFICATION_DIALOG) == null) {
// Prevent opening multiple dialogs if tapped on button quickly // Prevent opening multiple dialogs if tapped on button quickly
super.show(manager, tag); show(manager, TAG_UNIFICATION_DIALOG);
} }
} }
@@ -56,7 +58,8 @@ public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
: R.string.lock_settings_profile_unification_dialog_uncompliant_body) : R.string.lock_settings_profile_unification_dialog_uncompliant_body)
.setPositiveButton( .setPositiveButton(
compliant ? R.string.lock_settings_profile_unification_dialog_confirm compliant ? R.string.lock_settings_profile_unification_dialog_confirm
: R.string.lock_settings_profile_unification_dialog_uncompliant_confirm, : R.string
.lock_settings_profile_unification_dialog_uncompliant_confirm,
(dialog, whichButton) -> { (dialog, whichButton) -> {
if (compliant) { if (compliant) {
parentFragment.launchConfirmDeviceLockForUnification(); parentFragment.launchConfirmDeviceLockForUnification();

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2018 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 com.android.settings.security;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.Utils;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
public class VisiblePatternProfilePreferenceController extends TogglePreferenceController {
private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
private final LockPatternUtils mLockPatternUtils;
private final UserManager mUm;
private final int mUserId = UserHandle.myUserId();
private final int mProfileChallengeUserId;
public VisiblePatternProfilePreferenceController(Context context) {
super(context, KEY_VISIBLE_PATTERN_PROFILE);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
}
@Override
public int getAvailabilityStatus() {
if (mLockPatternUtils.isSecure(mProfileChallengeUserId)
&& mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
== PASSWORD_QUALITY_SOMETHING) {
return AVAILABLE;
}
return DISABLED_FOR_USER;
}
@Override
public boolean isChecked() {
return mLockPatternUtils.isVisiblePatternEnabled(
mProfileChallengeUserId);
}
@Override
public boolean setChecked(boolean isChecked) {
if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
return false;
}
mLockPatternUtils.setVisiblePatternEnabled(isChecked, mProfileChallengeUserId);
return true;
}
}

View File

@@ -16,6 +16,8 @@
package com.android.settings.security.trustagent; package com.android.settings.security.trustagent;
import static com.android.settings.security.SecuritySettingsV2.CHANGE_TRUST_AGENT_SETTINGS;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@@ -113,7 +115,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
final ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(mActivity, mHost); final ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(mActivity, mHost);
mTrustAgentClickIntent = preference.getIntent(); mTrustAgentClickIntent = preference.getIntent();
boolean confirmationLaunched = helper.launchConfirmationActivity( boolean confirmationLaunched = helper.launchConfirmationActivity(
SecuritySettingsV2.CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle()); CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
if (!confirmationLaunched && mTrustAgentClickIntent != null) { if (!confirmationLaunched && mTrustAgentClickIntent != null) {
// If this returns false, it means no password confirmation is required. // If this returns false, it means no password confirmation is required.
@@ -163,10 +165,14 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
} }
} }
public void handleActivityResult(int resultCode) { public boolean handleActivityResult(int requestCode, int resultCode) {
if (resultCode == Activity.RESULT_OK && mTrustAgentClickIntent != null) { if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) {
if (mTrustAgentClickIntent != null){
mHost.startActivity(mTrustAgentClickIntent); mHost.startActivity(mTrustAgentClickIntent);
mTrustAgentClickIntent = null; mTrustAgentClickIntent = null;
} }
return true;
}
return false;
} }
} }

View File

@@ -22,7 +22,6 @@ import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

View File

@@ -17,7 +17,6 @@
package com.android.settings.security; package com.android.settings.security;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@@ -35,14 +34,12 @@ import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.os.UserManager.EnforcingUser; import android.os.UserManager.EnforcingUser;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.dashboard.SummaryLoader; import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.XmlTestUtils;
@@ -161,24 +158,6 @@ public class SecuritySettingsTest {
R.plurals.manage_trust_agents_summary_on, 2, 2)); R.plurals.manage_trust_agents_summary_on, 2, 2));
} }
@Test
public void testSetLockscreenPreferencesSummary_shouldSetSummaryFromLockScreenNotification() {
final Preference preference = mock(Preference.class);
final PreferenceGroup group = mock(PreferenceGroup.class);
when(group.findPreference(SecuritySettings.KEY_LOCKSCREEN_PREFERENCES))
.thenReturn(preference);
final LockScreenNotificationPreferenceController controller =
mock(LockScreenNotificationPreferenceController.class);
final SecuritySettings securitySettings = new SecuritySettings();
ReflectionHelpers.setField(securitySettings,
"mLockScreenNotificationPreferenceController", controller);
when(controller.getSummaryResource()).thenReturn(1234);
securitySettings.setLockscreenPreferencesSummary(group);
verify(preference).setSummary(1234);
}
@Test @Test
public void testNonIndexableKeys_existInXmlLayout() { public void testNonIndexableKeys_existInXmlLayout() {
final Context context = spy(RuntimeEnvironment.application); final Context context = spy(RuntimeEnvironment.application);