Merge "Move Profile Security Settings into Security Settings" into nyc-dev

This commit is contained in:
Clara Bayarri
2016-02-23 17:25:08 +00:00
committed by Android (Google) Code Review
9 changed files with 362 additions and 400 deletions

View File

@@ -988,6 +988,9 @@
<!-- Title for security picker to choose the unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="lock_settings_picker_title">Choose screen lock</string>
<!-- Title for security picker to choose the profile unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="lock_settings_picker_title_profile">Choose profile screen lock</string>
<!-- Title for security picker in setup wizard to choose the unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="setup_lock_settings_picker_title">Protect your phone</string>
@@ -1008,6 +1011,10 @@
<!-- Title for PreferenceScreen to launch picker for security method when there is none [CHAR LIMIT=22] -->
<string name="unlock_set_unlock_launch_picker_title">Screen lock</string>
<!-- Profile Security lock settings --><skip />
<!-- Title for PreferenceScreen to launch picker for security method for the managed profile when there is none [CHAR LIMIT=22] -->
<string name="unlock_set_unlock_launch_picker_title_profile">Profile screen lock</string>
<!-- Title for PreferenceScreen to change security method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="unlock_set_unlock_launch_picker_change_title">Change lock screen</string>
@@ -3120,6 +3127,8 @@
<string name="lockpattern_settings_enable_summary">Must draw pattern to unlock screen</string>
<!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern. If checked, this line is drawn. If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
<string name="lockpattern_settings_enable_visible_pattern_title">Make pattern visible</string>
<!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the profile unlock pattern. If checked, this line is drawn. If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the profile.-->
<string name="lockpattern_settings_enable_visible_pattern_title_profile">Make profile pattern visible</string>
<!-- Security & location settings screen, setting check box title. This setting controls whether tactile feedback will be produced when the user draws the pattern.-->
<string name="lockpattern_settings_enable_tactile_feedback_title">Vibrate on tap</string>
<!-- Security & location settings screen, setting check box title. This controls whether the device locks immediately when the power button is pressed. [CHAR LIMIT=28]-->
@@ -5739,6 +5748,7 @@
<string name="keywords_color_temperature">color temperature D65 D73 white yellow blue warm cool</string>
<string name="keywords_lockscreen">slide to unlock, password, pattern, PIN</string>
<string name="keywords_profile_challenge">work challenge, work, profile</string>
<string name="keywords_unification">work profile, managed profile, unify, unification, work, profile</string>
<!-- NFC Wi-Fi pairing/setup strings-->

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/security_settings_title">
<PreferenceScreen
android:key="unlock_set_or_change_profile"
android:title="@string/unlock_set_unlock_launch_picker_title_profile"
android:summary="@string/unlock_set_unlock_mode_off"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
</PreferenceScreen>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/security_settings_title">
<PreferenceScreen
android:key="unlock_set_or_change_profile"
android:title="@string/unlock_set_unlock_launch_picker_title_profile"
android:summary="@string/unlock_set_unlock_mode_password"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
</PreferenceScreen>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/security_settings_title">
<PreferenceScreen
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"
android:persistent="false"/>
<SwitchPreference
android:key="visiblepattern_profile"
android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile"/>
</PreferenceScreen>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/security_settings_title">
<PreferenceScreen
android:key="unlock_set_or_change_profile"
android:title="@string/unlock_set_unlock_launch_picker_title_profile"
android:summary="@string/unlock_set_unlock_mode_pin"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
</PreferenceScreen>

View File

@@ -22,12 +22,6 @@
android:key="security_category_profile"
android:title="@string/lock_settings_profile_title">
<PreferenceScreen
android:key="profile_challenge"
android:title="@string/lock_settings_profile_label"
settings:keywords="@string/keywords_profile_challenge"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/security_settings_title">
<PreferenceScreen
android:key="unification"
android:title="@string/lock_settings_profile_unification_title"
android:summary="@string/lock_settings_profile_unification_summary"
settings:keywords="@string/keywords_unification"
android:persistent="false"/>
</PreferenceScreen>

View File

@@ -1,351 +0,0 @@
/*
* Copyright (C) 2016 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;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.util.Log;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.fingerprint.FingerprintEnrollIntroduction;
import com.android.settings.fingerprint.FingerprintSettings;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Settings for the Profile Challenge.
*/
public class ProfileChallengePreferenceFragment extends SettingsPreferenceFragment
implements OnPreferenceChangeListener {
private static final String TAG = "WorkChallengePreferenceFragment";
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
private static final String KEY_SECURITY_CATEGORY = "security_category";
private static final String KEY_UNIFICATION = "unification";
public static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
private static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 124;
private static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 125;
// Not all preferences make sense for the Work Challenge, this is a whitelist.
private static final Set<String> ALLOWED_PREFERENCE_KEYS = new HashSet<>();
{
ALLOWED_PREFERENCE_KEYS.add(KEY_UNLOCK_SET_OR_CHANGE);
ALLOWED_PREFERENCE_KEYS.add(KEY_VISIBLE_PATTERN);
}
// These switch preferences need special handling since they're not all stored in Settings.
private static final Set<String> SWITCH_PREFERENCE_KEYS = new HashSet<>();
{
SWITCH_PREFERENCE_KEYS.add(KEY_VISIBLE_PATTERN);
}
private LockPatternUtils mLockPatternUtils;
private int mProfileUserId;
private String mCurrentDevicePassword;
private String mCurrentProfilePassword;
private SwitchPreference mVisiblePattern;
@Override
protected int getMetricsCategory() {
return MetricsEvent.PROFILE_CHALLENGE;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getActivity());
mProfileUserId = getArguments().getInt(Intent.EXTRA_USER_ID, -1);
if (mProfileUserId == -1) {
finish();
}
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
final String key = preference.getKey();
if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileUserId);
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, extras);
return true;
} else if (KEY_UNIFICATION.equals(key)) {
UnificationConfirmationDialog dialog =
UnificationConfirmationDialog.newIntance(mProfileUserId);
dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
return true;
}
return super.onPreferenceTreeClick(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
final String key = preference.getKey();
if (KEY_VISIBLE_PATTERN.equals(key)) {
mLockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileUserId);
return true;
}
return false;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST && resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword =
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;
}
}
private void launchConfirmDeviceLockForUnification() {
final String title = getActivity().getString(
R.string.lock_settings_profile_screen_lock_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, UserHandle.myUserId())) {
launchConfirmProfileLockForUnification();
}
}
private void launchConfirmProfileLockForUnification() {
final String title = getActivity().getString(
R.string.lock_settings_profile_screen_lock_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileUserId)) {
unifyLocks();
createPreferenceHierarchy();
}
}
private void unifyLocks() {
int profileQuality = mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileUserId);
mLockPatternUtils.clearLock(mProfileUserId);
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileUserId, false);
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.stringToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, UserHandle.myUserId());
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword,
profileQuality, UserHandle.myUserId());
}
mCurrentDevicePassword = null;
mCurrentProfilePassword = null;
}
@Override
public void onResume() {
super.onResume();
// Make sure we reload the preference hierarchy since some of these settings
// depend on others...
createPreferenceHierarchy();
if (mVisiblePattern != null) {
mVisiblePattern.setChecked(mLockPatternUtils.isVisiblePatternEnabled(
mProfileUserId));
}
}
private void createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
addPreferencesFromResource(R.xml.profile_challenge_settings);
root = getPreferenceScreen();
// Add options for lock/unlock screen
final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils);
addPreferencesFromResource(resid);
mVisiblePattern = (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN);
removeNonWhitelistedItems(root);
PreferenceGroup securityCategory = (PreferenceGroup)
root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null) {
maybeAddFingerprintPreference(securityCategory);
if (mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileUserId)) {
maybeAddUnificationPreference(securityCategory);
} else {
Preference lockPreference =
securityCategory.findPreference(KEY_UNLOCK_SET_OR_CHANGE);
String summary =
getContext().getString(R.string.lock_settings_profile_unified_summary);
lockPreference.setSummary(summary);
}
}
}
private void maybeAddUnificationPreference(PreferenceGroup securityCategory) {
if (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(mProfileUserId)) {
Preference unificationPreference = new Preference(securityCategory.getContext());
unificationPreference.setKey(KEY_UNIFICATION);
unificationPreference.setTitle(R.string.lock_settings_profile_unification_title);
unificationPreference.setSummary(R.string.lock_settings_profile_unification_summary);
securityCategory.addPreference(unificationPreference);
}
}
private void maybeAddFingerprintPreference(PreferenceGroup securityCategory) {
Preference fingerprintPreference =
FingerprintSettings.getFingerprintPreferenceForUser(getActivity(), mProfileUserId);
if (fingerprintPreference != null) {
securityCategory.addPreference(fingerprintPreference);
}
}
private void removeNonWhitelistedItems(PreferenceGroup prefScreen) {
int numPreferences = prefScreen.getPreferenceCount();
int i = 0;
while (i < numPreferences) {
final Preference pref = prefScreen.getPreference(i);
// Recursively look into categories and remove them if they are empty.
if (pref instanceof PreferenceCategory) {
PreferenceCategory category = (PreferenceCategory) pref;
removeNonWhitelistedItems(category);
if (category.getPreferenceCount() == 0) {
prefScreen.removePreference(category);
--i;
--numPreferences;
}
} else if (ALLOWED_PREFERENCE_KEYS.contains(pref.getKey())) {
if (SWITCH_PREFERENCE_KEYS.contains(pref.getKey())) {
pref.setOnPreferenceChangeListener(this);
}
} else {
prefScreen.removePreference(pref);
--i;
--numPreferences;
}
++i;
}
}
private int getResIdForLockUnlockScreen(Context context,
LockPatternUtils lockPatternUtils) {
int resid = 0;
if (!lockPatternUtils.isSecure(mProfileUserId)) {
resid = R.xml.security_settings_lockscreen;
} else {
switch (lockPatternUtils.getKeyguardStoredPasswordQuality(mProfileUserId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
resid = R.xml.security_settings_pattern;
break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
resid = R.xml.security_settings_pin;
break;
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
resid = R.xml.security_settings_password;
break;
}
}
return resid;
}
public static class UnificationConfirmationDialog extends DialogFragment {
public static UnificationConfirmationDialog newIntance(int userId) {
UnificationConfirmationDialog dialog = new UnificationConfirmationDialog();
return dialog;
}
@Override
public void show(FragmentManager manager, String tag) {
if (manager.findFragmentByTag(tag) == null) {
// Prevent opening multiple dialogs if tapped on button quickly
super.show(manager, tag);
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final ProfileChallengePreferenceFragment parentFragment =
((ProfileChallengePreferenceFragment) getParentFragment());
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
.setMessage(R.string.lock_settings_profile_unification_dialog_body)
.setPositiveButton(R.string.okay,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
parentFragment.launchConfirmDeviceLockForUnification();
}
}
)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
dismiss();
}
}
)
.create();
}
}
}

View File

@@ -19,6 +19,9 @@ package com.android.settings;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
@@ -85,14 +88,20 @@ public class SecuritySettings extends SettingsPreferenceFragment
// Lock Settings
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "profile_challenge";
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_DEVICE_ADMIN_CATEGORY = "device_admin_category";
private static final String KEY_ADVANCED_SECURITY = "advanced_security";
private static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
private static final String KEY_UNIFICATION = "unification";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
private static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
private static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
private static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
private static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
// Misc Settings
private static final String KEY_SIM_LOCK = "sim_lock";
@@ -122,6 +131,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private LockPatternUtils mLockPatternUtils;
private SwitchPreference mVisiblePatternProfile;
private SwitchPreference mShowPassword;
private KeyStore mKeyStore;
@@ -136,6 +147,9 @@ public class SecuritySettings extends SettingsPreferenceFragment
private int mProfileChallengeUserId;
private String mCurrentDevicePassword;
private String mCurrentProfilePassword;
@Override
protected int getMetricsCategory() {
return MetricsEvent.SECURITY;
@@ -162,27 +176,33 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
private static int getResIdForLockUnlockScreen(Context context,
LockPatternUtils lockPatternUtils) {
LockPatternUtils lockPatternUtils, int userId) {
final boolean isMyUser = userId == MY_USER_ID;
int resid = 0;
if (!lockPatternUtils.isSecure(MY_USER_ID)) {
if (lockPatternUtils.isLockScreenDisabled(MY_USER_ID)) {
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(MY_USER_ID)) {
switch (lockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
resid = R.xml.security_settings_pattern;
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 = R.xml.security_settings_pin;
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 = R.xml.security_settings_password;
resid = isMyUser ? R.xml.security_settings_password
: R.xml.security_settings_password_profile;
break;
}
}
@@ -204,20 +224,24 @@ public class SecuritySettings extends SettingsPreferenceFragment
root = getPreferenceScreen();
// Add options for lock/unlock screen
final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils);
final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils, MY_USER_ID);
addPreferencesFromResource(resid);
List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId());
int numProfiles = profiles.size();
if (numProfiles > 1) {
for (int i = 0; i < numProfiles; ++i) {
UserInfo profile = profiles.get(i);
if (profile.id != UserHandle.myUserId()) {
mProfileChallengeUserId = profile.id;
}
}
if (mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
addPreferencesFromResource(R.xml.security_settings_profile);
mProfileChallengeUserId = getManagedProfileId(mUm);
if (mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
addPreferencesFromResource(R.xml.security_settings_profile);
final int profileResid = getResIdForLockUnlockScreen(
getActivity(), mLockPatternUtils, mProfileChallengeUserId);
addPreferencesFromResource(profileResid);
maybeAddFingerprintPreference(root, mProfileChallengeUserId);
if (mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
maybeAddUnificationPreference();
} else {
Preference lockPreference = root.findPreference(KEY_UNLOCK_SET_OR_CHANGE_PROFILE);
String summary = getContext().getString(
R.string.lock_settings_profile_unified_summary);
lockPreference.setSummary(summary);
}
}
@@ -243,10 +267,13 @@ public class SecuritySettings extends SettingsPreferenceFragment
PreferenceGroup securityCategory = (PreferenceGroup)
root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null) {
maybeAddFingerprintPreference(securityCategory);
maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
addTrustAgentSettings(securityCategory);
}
mVisiblePatternProfile =
(SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
// Append the rest of the settings
addPreferencesFromResource(R.xml.security_settings_misc);
@@ -350,15 +377,24 @@ public class SecuritySettings extends SettingsPreferenceFragment
return root;
}
private void maybeAddFingerprintPreference(PreferenceGroup securityCategory) {
private void maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId) {
Preference fingerprintPreference =
FingerprintSettings.getFingerprintPreferenceForUser(
securityCategory.getContext(), UserHandle.myUserId());
securityCategory.getContext(), userId);
if (fingerprintPreference != null) {
securityCategory.addPreference(fingerprintPreference);
}
}
private void maybeAddUnificationPreference() {
if (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
mProfileChallengeUserId)) {
addPreferencesFromResource(R.xml.security_settings_unification);
}
}
private void addTrustAgentSettings(PreferenceGroup securityCategory) {
final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
ArrayList<TrustAgentComponentInfo> agents =
@@ -525,6 +561,11 @@ public class SecuritySettings extends SettingsPreferenceFragment
createPreferenceHierarchy();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (mVisiblePatternProfile != null) {
mVisiblePatternProfile.setChecked(lockPatternUtils.isVisiblePatternEnabled(
mProfileChallengeUserId));
}
if (mShowPassword != null) {
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
@@ -544,8 +585,9 @@ public class SecuritySettings extends SettingsPreferenceFragment
} else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
startFragment(this, "com.android.settings.ProfileChallengePreferenceFragment",
R.string.lock_settings_profile_label, SET_OR_CHANGE_LOCK_METHOD_REQUEST, extras);
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
} else if (KEY_TRUST_AGENT.equals(key)) {
ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(this.getActivity(), this);
@@ -557,6 +599,11 @@ public class SecuritySettings extends SettingsPreferenceFragment
startActivity(mTrustAgentClickIntent);
mTrustAgentClickIntent = null;
}
} else if (KEY_UNIFICATION.equals(key)) {
UnificationConfirmationDialog dialog =
UnificationConfirmationDialog.newIntance(mProfileChallengeUserId);
dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
return true;
} else {
// If we didn't handle it, let preferences handle it.
return super.onPreferenceTreeClick(preference);
@@ -576,16 +623,71 @@ public class SecuritySettings extends SettingsPreferenceFragment
mTrustAgentClickIntent = null;
}
return;
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword =
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;
}
createPreferenceHierarchy();
}
private void launchConfirmDeviceLockForUnification() {
final String title = getActivity().getString(
R.string.lock_settings_profile_screen_lock_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, UserHandle.myUserId())) {
launchConfirmProfileLockForUnification();
}
}
private void launchConfirmProfileLockForUnification() {
final String title = getActivity().getString(
R.string.lock_settings_profile_screen_lock_title);
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);
mLockPatternUtils.clearLock(mProfileChallengeUserId);
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false);
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.stringToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, UserHandle.myUserId());
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword,
profileQuality, UserHandle.myUserId());
}
mCurrentDevicePassword = null;
mCurrentProfilePassword = null;
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
boolean result = true;
final String key = preference.getKey();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (KEY_SHOW_PASSWORD.equals(key)) {
if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
} else if (KEY_SHOW_PASSWORD.equals(key)) {
Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
((Boolean) value) ? 1 : 0);
lockPatternUtils.setVisiblePasswordEnabled((Boolean) value, MY_USER_ID);
@@ -607,6 +709,21 @@ public class SecuritySettings extends SettingsPreferenceFragment
return R.string.help_url_security;
}
private static int getManagedProfileId(UserManager um) {
List<UserInfo> profiles = um.getProfiles(MY_USER_ID);
int numProfiles = profiles.size();
if (numProfiles == 1) {
return UserHandle.USER_NULL;
}
for (int i = 0; i < numProfiles; ++i) {
UserInfo profile = profiles.get(i);
if (profile.id != MY_USER_ID) {
return profile.id;
}
}
return UserHandle.USER_NULL;
}
/**
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/
@@ -623,28 +740,20 @@ public class SecuritySettings extends SettingsPreferenceFragment
LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
// Add options for lock/unlock screen
int resId = getResIdForLockUnlockScreen(context, lockPatternUtils);
int resId = getResIdForLockUnlockScreen(context, lockPatternUtils, MY_USER_ID);
SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = resId;
result.add(sir);
final UserManager um = UserManager.get(context);
List<UserInfo> profiles = um.getProfiles(UserHandle.myUserId());
int numProfiles = profiles.size();
if (numProfiles > 1) {
int profileUserId = -1;
for (int i = 0; i < numProfiles; ++i) {
UserInfo profile = profiles.get(i);
if (profile.id != UserHandle.myUserId()) {
profileUserId = profile.id;
}
}
if (lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.security_settings_profile;
result.add(sir);
}
final int profileUserId = getManagedProfileId(um);
if (profileUserId != UserHandle.USER_NULL
&& lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
sir = new SearchIndexableResource(context);
sir.xmlResId = getResIdForLockUnlockScreen(
context, lockPatternUtils, profileUserId);
result.add(sir);
}
if (um.isAdminUser()) {
@@ -720,6 +829,21 @@ public class SecuritySettings extends SettingsPreferenceFragment
result.add(data);
}
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
final int profileUserId = getManagedProfileId(um);
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.screenTitle = screenTitle;
result.add(data);
}
}
// Credential storage
if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) {
KeyStore keyStore = KeyStore.getInstance();
@@ -735,7 +859,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
// Advanced
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
if (lockPatternUtils.isSecure(MY_USER_ID)) {
ArrayList<TrustAgentComponentInfo> agents =
getActiveTrustAgents(context, lockPatternUtils,
@@ -1080,4 +1203,46 @@ public class SecuritySettings extends SettingsPreferenceFragment
return true;
}
}
public static class UnificationConfirmationDialog extends DialogFragment {
public static UnificationConfirmationDialog newIntance(int userId) {
UnificationConfirmationDialog dialog = new UnificationConfirmationDialog();
return dialog;
}
@Override
public void show(FragmentManager manager, String tag) {
if (manager.findFragmentByTag(tag) == null) {
// Prevent opening multiple dialogs if tapped on button quickly
super.show(manager, tag);
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final SecuritySettings parentFragment = ((SecuritySettings) getParentFragment());
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
.setMessage(R.string.lock_settings_profile_unification_dialog_body)
.setPositiveButton(R.string.okay,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
parentFragment.launchConfirmDeviceLockForUnification();
}
}
)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
dismiss();
}
}
)
.create();
}
}
}