Files
app_Settings/src/com/android/settings/ProfileChallengePreferenceFragment.java
Clara Bayarri 40db4bbbb5 Profile Challenge Fingerprint Support
Change-Id: Ic83c479f645776dd0678721bfb732b399f09c992
2016-01-26 15:45:37 +00:00

351 lines
14 KiB
Java

/*
* 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.MetricsLogger;
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 MetricsLogger.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) {
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();
}
}
}