Move lock screen setting behind gear

Bug: 19003093
Change-Id: I15baa5b1d19324521070d641ae6a227d782a4e9e
This commit is contained in:
Adrian Roos
2016-01-28 13:23:53 -08:00
parent a7accd2064
commit 62775bf756
18 changed files with 629 additions and 262 deletions

View File

@@ -7024,6 +7024,18 @@
<!-- No default home set summary [CHAR LIMIT=NONE] -->
<string name="no_default_home">No default Home</string>
<!-- Title of the preference controlling whether the device encryption password/PIN/Pattern must be entered before being able to start the device. [CHAR LIMIT=60]-->
<string name="lockpattern_settings_require_cred_before_startup">Secure start-up</string>
<!-- Summary of the preference controlling whether the device encryption *pattern* must be entered before being able to start the device. [CHAR LIMIT=NONE]-->
<string name="lockpattern_settings_require_pattern_before_startup_summary">Require pattern to start up your device. While off, this device can\'t receive calls, messages, notifications, or alarms.</string>
<!-- Summary of the preference controlling whether the device encryption *PIN* must be entered before being able to start the device. [CHAR LIMIT=NONE]-->
<string name="lockpattern_settings_require_pin_before_startup_summary">Require PIN to start up your device. While off, this device can\'t receive calls, messages, notifications, or alarms.</string>
<!-- Summary of the preference controlling whether the device encryption *password* must be entered before being able to start the device. [CHAR LIMIT=NONE]-->
<string name="lockpattern_settings_require_password_before_startup_summary">Require password to start up your device. While off, this device can\'t receive calls, messages, notifications, or alarms.</string>
<!-- Title for suggestion adding more fingerprints [CHAR LIMIT=30] -->
<string name="suggestion_additional_fingerprints">Additional Fingerprints</string>

View File

@@ -15,23 +15,20 @@
-->
<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">
<PreferenceCategory
android:key="security_category"
android:title="@string/lock_settings_title">
<PreferenceScreen
<com.android.settings.GearPreference
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_title"
android:summary="@string/unlock_set_unlock_mode_none"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -29,12 +29,6 @@
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:enabled="false"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -22,30 +22,13 @@
android:key="security_category"
android:title="@string/lock_settings_title">
<PreferenceScreen
<com.android.settings.GearPreference
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_title"
android:summary="@string/unlock_set_unlock_mode_password"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
<com.android.settings.RestrictedListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values"
android:persistent="false"/>
<SwitchPreference
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,45 @@
<?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/settings_label">
<com.android.settings.RestrictedListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values"
android:persistent="false"/>
<SwitchPreference
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<SwitchPreference
android:key="require_cred_before_startup"
android:title="@string/lockpattern_settings_require_cred_before_startup"
android:summary="@string/lockpattern_settings_require_password_before_startup_summary"/>
</PreferenceScreen>

View File

@@ -22,34 +22,13 @@
android:key="security_category"
android:title="@string/lock_settings_title">
<PreferenceScreen
<com.android.settings.GearPreference
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_title"
android:summary="@string/unlock_set_unlock_mode_pattern"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
<SwitchPreference
android:key="visiblepattern"
android:title="@string/lockpattern_settings_enable_visible_pattern_title"/>
<com.android.settings.RestrictedListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values"
android:persistent="false"/>
<SwitchPreference
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,49 @@
<?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/settings_label">
<SwitchPreference
android:key="visiblepattern"
android:title="@string/lockpattern_settings_enable_visible_pattern_title"/>
<com.android.settings.RestrictedListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values"
android:persistent="false"/>
<SwitchPreference
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<SwitchPreference
android:key="require_cred_before_startup"
android:title="@string/lockpattern_settings_require_cred_before_startup"
android:summary="@string/lockpattern_settings_require_pattern_before_startup_summary"/>
</PreferenceScreen>

View File

@@ -22,30 +22,13 @@
android:key="security_category"
android:title="@string/lock_settings_title">
<PreferenceScreen
<com.android.settings.GearPreference
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_title"
android:summary="@string/unlock_set_unlock_mode_pin"
settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/>
<com.android.settings.RestrictedListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values"
android:persistent="false"/>
<SwitchPreference
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,45 @@
<?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/settings_label">
<com.android.settings.RestrictedListPreference
android:key="lock_after_timeout"
android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary"
android:entries="@array/lock_after_timeout_entries"
android:entryValues="@array/lock_after_timeout_values"
android:persistent="false"/>
<SwitchPreference
android:key="power_button_instantly_locks"
android:title="@string/lockpattern_settings_enable_power_button_instantly_locks"/>
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
<SwitchPreference
android:key="require_cred_before_startup"
android:title="@string/lockpattern_settings_require_cred_before_startup"
android:summary="@string/lockpattern_settings_require_pin_before_startup_summary"/>
</PreferenceScreen>

View File

@@ -0,0 +1,27 @@
<?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/settings_label">
<com.android.settings.SingleLineSummaryPreference
android:key="owner_info_settings"
android:title="@string/owner_info_settings_title"
android:summary="@string/owner_info_settings_summary"/>
</PreferenceScreen>

View File

@@ -37,6 +37,7 @@ import android.os.UserManager;
import android.security.KeyStore;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.view.View;
@@ -104,6 +105,7 @@ public class ChooseLockGeneric extends SettingsActivity {
private boolean mEncryptionRequestDisabled;
private boolean mRequirePassword;
private boolean mForFingerprint = false;
private boolean mForChangeCredRequiredForBoot = false;
private String mUserPassword;
private LockPatternUtils mLockPatternUtils;
private FingerprintManager mFingerprintManager;
@@ -157,6 +159,8 @@ public class ChooseLockGeneric extends SettingsActivity {
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
mForFingerprint = getActivity().getIntent().getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
if (savedInstanceState != null) {
mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
@@ -183,6 +187,10 @@ public class ChooseLockGeneric extends SettingsActivity {
if (mPasswordConfirmed) {
updatePreferencesOrFinish();
if (mForChangeCredRequiredForBoot) {
maybeEnableEncryption(mLockPatternUtils.getKeyguardStoredPasswordQuality(
mUserId), false);
}
} else if (!mWaitingForConfirmation) {
ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(this.getActivity(), this);
@@ -238,6 +246,9 @@ public class ChooseLockGeneric extends SettingsActivity {
// Get the intent that the encryption interstitial should start for creating
// the new unlock method.
Intent unlockMethodIntent = getIntentForUnlockMethod(quality, disabled);
unlockMethodIntent.putExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT,
mForChangeCredRequiredForBoot);
final Context context = getActivity();
// If accessibility is enabled and the user hasn't seen this dialog before, set the
// default state to agree with that which is compatible with accessibility
@@ -250,6 +261,11 @@ public class ChooseLockGeneric extends SettingsActivity {
mForFingerprint);
startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
} else {
if (mForChangeCredRequiredForBoot) {
// Welp, couldn't change it. Oh well.
finish();
return;
}
mRequirePassword = false; // device encryption not enabled or not device owner.
updateUnlockMethodAndFinish(quality, disabled);
}
@@ -263,6 +279,14 @@ public class ChooseLockGeneric extends SettingsActivity {
mPasswordConfirmed = true;
mUserPassword = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
updatePreferencesOrFinish();
if (mForChangeCredRequiredForBoot) {
if (!TextUtils.isEmpty(mUserPassword)) {
maybeEnableEncryption(
mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false);
} else {
finish();
}
}
} else if (requestCode == CHOOSE_LOCK_REQUEST
|| requestCode == ENABLE_ENCRYPTION_REQUEST) {
if (resultCode != RESULT_CANCELED) {
@@ -273,6 +297,9 @@ public class ChooseLockGeneric extends SettingsActivity {
getActivity().setResult(Activity.RESULT_CANCELED);
finish();
}
if (requestCode == Activity.RESULT_CANCELED && mForChangeCredRequiredForBoot) {
finish();
}
}
@Override

View File

@@ -267,6 +267,19 @@ public class ChooseLockPassword extends SettingsActivity {
mUserId));
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
if (intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
String current = intent.getStringExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true);
w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required,
false, 0, current, current, mRequestedQuality, mUserId);
}
}
@Override

View File

@@ -371,6 +371,19 @@ public class ChooseLockPattern extends SettingsActivity {
Intent intent = getActivity().getIntent();
// Only take this argument into account if it belongs to the current profile.
mUserId = Utils.getUserIdFromBundle(getActivity(), intent.getExtras());
if (intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
SaveAndFinishWorker w = new SaveAndFinishWorker();
final boolean required = getActivity().getIntent().getBooleanExtra(
EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
String current = intent.getStringExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
w.setBlocking(true);
w.setListener(this);
w.start(mChooseLockSettingsHelper.utils(), required,
false, 0, LockPatternUtils.stringToPattern(current), current, mUserId);
}
}
@Override

View File

@@ -33,6 +33,7 @@ public final class ChooseLockSettingsHelper {
public static final String EXTRA_KEY_CHALLENGE = "challenge";
public static final String EXTRA_KEY_CHALLENGE_TOKEN = "hw_auth_token";
public static final String EXTRA_KEY_FOR_FINGERPRINT = "for_fingerprint";
public static final String EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT = "for_cred_req_boot";
private LockPatternUtils mLockPatternUtils;

View File

@@ -0,0 +1,59 @@
/*
* 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.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.view.View;
/**
* A preference with a Gear on the side
*/
public class GearPreference extends Preference implements View.OnClickListener {
private OnGearClickListener mOnGearClickListener;
public GearPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setWidgetLayoutResource(R.layout.preference_widget_settings);
}
public void setOnGearClickListener(OnGearClickListener l) {
mOnGearClickListener = l;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.findViewById(R.id.settings_button).setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.settings_button) {
if (mOnGearClickListener != null) {
mOnGearClickListener.onGearClick(this);
}
}
}
public interface OnGearClickListener {
void onGearClick(GearPreference p);
}
}

View File

@@ -75,8 +75,8 @@ public class OwnerInfoSettings extends DialogFragment implements OnClickListener
mLockPatternUtils.setOwnerInfoEnabled(!TextUtils.isEmpty(info), mUserId);
mLockPatternUtils.setOwnerInfo(info, mUserId);
if (getTargetFragment() instanceof SecuritySettings) {
((SecuritySettings) getTargetFragment()).updateOwnerInfo();
if (getTargetFragment() instanceof SecuritySettings.SecuritySubSettings) {
((SecuritySettings.SecuritySubSettings) getTargetFragment()).updateOwnerInfo();
}
}
}

View File

@@ -39,6 +39,8 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
protected boolean mWasSecureBefore;
protected int mUserId;
private boolean mBlocking;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -74,7 +76,11 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
}
protected void start() {
new Task().execute();
if (mBlocking) {
finish(saveAndVerifyInBackground());
} else {
new Task().execute();
}
}
/**
@@ -91,6 +97,10 @@ abstract class SaveChosenLockWorkerBase extends Fragment {
}
}
public void setBlocking(boolean blocking) {
mBlocking = blocking;
}
private class Task extends AsyncTask<Void, Void, Intent> {
@Override
protected Intent doInBackground(Void... params){

View File

@@ -28,7 +28,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.PersistableBundle;
@@ -55,7 +54,6 @@ import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.RestrictedListPreference;
import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo;
import com.android.settings.fingerprint.FingerprintEnrollIntroduction;
import com.android.settings.fingerprint.FingerprintSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Index;
@@ -77,7 +75,8 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
* Gesture lock pattern settings.
*/
public class SecuritySettings extends SettingsPreferenceFragment
implements OnPreferenceChangeListener, DialogInterface.OnClickListener, Indexable {
implements OnPreferenceChangeListener, DialogInterface.OnClickListener, Indexable,
GearPreference.OnGearClickListener {
private static final String TAG = "SecuritySettings";
private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent";
@@ -87,11 +86,8 @@ 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_VISIBLE_PATTERN = "visiblepattern";
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_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
private static final String KEY_OWNER_INFO_SETTINGS = "owner_info_settings";
private static final String KEY_ADVANCED_SECURITY = "advanced_security";
private static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
@@ -105,16 +101,14 @@ public class SecuritySettings extends SettingsPreferenceFragment
private static final String KEY_RESET_CREDENTIALS = "credentials_reset";
private static final String KEY_CREDENTIALS_INSTALL = "credentials_install";
private static final String KEY_TOGGLE_INSTALL_APPLICATIONS = "toggle_install_applications";
private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
private static final String KEY_CREDENTIALS_MANAGER = "credentials_management";
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
private static final String KEY_TRUST_AGENT = "trust_agent";
private static final String KEY_SCREEN_PINNING = "screen_pinning_settings";
// These switch preferences need special handling since they're not all stored in Settings.
private static final String SWITCH_PREFERENCE_KEYS[] = { KEY_LOCK_AFTER_TIMEOUT,
KEY_VISIBLE_PATTERN, KEY_POWER_INSTANTLY_LOCKS, KEY_SHOW_PASSWORD,
KEY_TOGGLE_INSTALL_APPLICATIONS };
private static final String SWITCH_PREFERENCE_KEYS[] = {
KEY_SHOW_PASSWORD, KEY_TOGGLE_INSTALL_APPLICATIONS };
// Only allow one trust agent on the platform.
private static final boolean ONLY_ONE_TRUST_AGENT = true;
@@ -127,9 +121,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private LockPatternUtils mLockPatternUtils;
private RestrictedListPreference mLockAfter;
private SwitchPreference mVisiblePattern;
private SwitchPreference mShowPassword;
@@ -138,12 +129,10 @@ public class SecuritySettings extends SettingsPreferenceFragment
private RestrictedSwitchPreference mToggleAppInstallation;
private DialogInterface mWarnInstallApps;
private SwitchPreference mPowerButtonInstantlyLocks;
private boolean mIsAdmin;
private Intent mTrustAgentClickIntent;
private Preference mOwnerInfoPref;
private int mProfileChallengeUserId;
@@ -232,25 +221,14 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
}
Preference unlockSetOrChange = findPreference(KEY_UNLOCK_SET_OR_CHANGE);
if (unlockSetOrChange instanceof GearPreference) {
((GearPreference) unlockSetOrChange).setOnGearClickListener(this);
}
// Add options for device encryption
mIsAdmin = mUm.isAdminUser();
mOwnerInfoPref = findPreference(KEY_OWNER_INFO_SETTINGS);
if (mOwnerInfoPref != null) {
mOwnerInfoPref.setEnabled(!mLockPatternUtils.isLockScreenDisabled(MY_USER_ID)
&& !mLockPatternUtils.isDeviceOwnerInfoEnabled());
if (mOwnerInfoPref.isEnabled()) {
mOwnerInfoPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
OwnerInfoSettings.show(SecuritySettings.this);
return true;
}
});
}
}
if (mIsAdmin) {
if (LockPatternUtils.isDeviceEncryptionEnabled()) {
// The device is currently encrypted.
@@ -269,28 +247,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
addTrustAgentSettings(securityCategory);
}
// lock after preference
mLockAfter = (RestrictedListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT);
if (mLockAfter != null) {
setupLockAfterPreference();
updateLockAfterPreferenceSummary();
}
// visible pattern
mVisiblePattern = (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN);
// lock instantly on power key press
mPowerButtonInstantlyLocks = (SwitchPreference) root.findPreference(
KEY_POWER_INSTANTLY_LOCKS);
Preference trustAgentPreference = root.findPreference(KEY_TRUST_AGENT);
if (mPowerButtonInstantlyLocks != null &&
trustAgentPreference != null &&
trustAgentPreference.getTitle().length() > 0) {
mPowerButtonInstantlyLocks.setSummary(getString(
R.string.lockpattern_settings_power_button_instantly_locks_summary,
trustAgentPreference.getTitle()));
}
// Append the rest of the settings
addPreferencesFromResource(R.xml.security_settings_misc);
@@ -521,6 +477,13 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
}
@Override
public void onGearClick(GearPreference p) {
if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
startFragment(this, SecuritySubSettings.class.getName(), 0, 0, null);
}
}
@Override
public void onDestroy() {
super.onDestroy();
@@ -529,105 +492,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
}
}
private void setupLockAfterPreference() {
// Compatible with pre-Froyo
long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
mLockAfter.setValue(String.valueOf(currentTimeout));
mLockAfter.setOnPreferenceChangeListener(this);
final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
getActivity());
if (admin != null) {
final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0);
final long displayTimeout = Math.max(0,
Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
if (adminTimeout > 0) {
// This setting is a slave to display timeout when a device policy is enforced.
// As such, maxLockTimeout = adminTimeout - displayTimeout.
// If there isn't enough time, shows "immediately" setting.
disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout), admin);
}
}
}
private void updateLockAfterPreferenceSummary() {
final String summary;
if (mLockAfter.isDisabledByAdmin()) {
summary = getString(R.string.disabled_by_policy_title);
} else {
// Update summary message with current value
long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
final CharSequence[] entries = mLockAfter.getEntries();
final CharSequence[] values = mLockAfter.getEntryValues();
int best = 0;
for (int i = 0; i < values.length; i++) {
if (mLockAfter.isRestrictedForEntry(entries[i])) {
break;
}
long timeout = Long.valueOf(values[i].toString());
if (currentTimeout >= timeout) {
best = i;
}
}
Preference preference = getPreferenceScreen().findPreference(KEY_TRUST_AGENT);
if (preference != null && preference.getTitle().length() > 0) {
if (Long.valueOf(values[best].toString()) == 0) {
summary = getString(R.string.lock_immediately_summary_with_exception,
preference.getTitle());
} else {
summary = getString(R.string.lock_after_timeout_summary_with_exception,
entries[best], preference.getTitle());
}
} else {
summary = getString(R.string.lock_after_timeout_summary, entries[best]);
}
}
mLockAfter.setSummary(summary);
}
private void disableUnusableTimeouts(long maxTimeout, EnforcedAdmin admin) {
final CharSequence[] entries = mLockAfter.getEntries();
final CharSequence[] values = mLockAfter.getEntryValues();
long maxTimeoutSelectable = 0;
int maxTimeoutEntryIndex = -1;
for (int i = 0; i < values.length; i++) {
long timeout = Long.parseLong(values[i].toString());
if (timeout > maxTimeout) {
break;
}
maxTimeoutSelectable = timeout;
maxTimeoutEntryIndex = i;
}
// If there are no possible options for the user, then set this preference as
// disabled by admin, otherwise remove the padlock in case it was set earlier.
if (maxTimeoutSelectable == 0) {
mLockAfter.setDisabledByAdmin(admin);
return;
} else {
mLockAfter.setDisabledByAdmin(null);
}
mLockAfter.clearRestrictedItems();
// Set all the entries after the maximum selectable timeout as disabled by admin.
for (int i = maxTimeoutEntryIndex + 1; i < values.length; i++) {
mLockAfter.addRestrictedItem(
new RestrictedItem(entries[i], values[i], admin));
}
final int userPreference = Integer.valueOf(mLockAfter.getValue());
if (userPreference <= maxTimeout) {
mLockAfter.setValue(String.valueOf(userPreference));
} else if (maxTimeoutSelectable == maxTimeout) {
mLockAfter.setValue(String.valueOf(maxTimeout));
} else {
// There will be no highlighted selection since nothing in the list matches
// maxTimeout. The user can still select anything less than maxTimeout.
// TODO: maybe append maxTimeout to the list and mark selected.
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -645,15 +509,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
createPreferenceHierarchy();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (mVisiblePattern != null) {
mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled(
MY_USER_ID));
}
if (mPowerButtonInstantlyLocks != null) {
mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks(
MY_USER_ID));
}
if (mShowPassword != null) {
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
@@ -662,20 +517,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
if (mResetCredentials != null) {
mResetCredentials.setEnabled(!mKeyStore.isEmpty());
}
updateOwnerInfo();
}
public void updateOwnerInfo() {
if (mOwnerInfoPref != null) {
if (mLockPatternUtils.isDeviceOwnerInfoEnabled()) {
mOwnerInfoPref.setSummary(R.string.disabled_by_administrator_summary);
} else {
mOwnerInfoPref.setSummary(mLockPatternUtils.isOwnerInfoEnabled(MY_USER_ID)
? mLockPatternUtils.getOwnerInfo(MY_USER_ID)
: getString(R.string.owner_info_settings_summary));
}
}
}
@Override
@@ -728,20 +569,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
boolean result = true;
final String key = preference.getKey();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (KEY_LOCK_AFTER_TIMEOUT.equals(key)) {
int timeout = Integer.parseInt((String) value);
try {
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
} catch (NumberFormatException e) {
Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e);
}
updateLockAfterPreferenceSummary();
} else if (KEY_VISIBLE_PATTERN.equals(key)) {
lockPatternUtils.setVisiblePatternEnabled((Boolean) value, MY_USER_ID);
} else if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) {
mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value, MY_USER_ID);
} else if (KEY_SHOW_PASSWORD.equals(key)) {
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);
@@ -823,6 +651,12 @@ public class SecuritySettings extends SettingsPreferenceFragment
result.add(sir);
}
sir = new SearchIndexableResource(context);
sir.xmlResId = SecuritySubSettings.getResIdForLockUnlockSubScreen(context,
lockPatternUtils);
sir.className = SecuritySubSettings.class.getName();
result.add(sir);
// Append the rest of the settings
sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.security_settings_misc;
@@ -924,8 +758,304 @@ public class SecuritySettings extends SettingsPreferenceFragment
keys.add(KEY_MANAGE_TRUST_AGENTS);
}
if (!SecuritySubSettings.canChangeRequireCredentialBeforeStartup(context)) {
keys.add(SecuritySubSettings.KEY_REQUIRE_CRED_BEFORE_STARTUP);
}
return keys;
}
}
public static class SecuritySubSettings extends SettingsPreferenceFragment
implements OnPreferenceChangeListener {
private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
private static final String KEY_OWNER_INFO_SETTINGS = "owner_info_settings";
private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
private static final String KEY_REQUIRE_CRED_BEFORE_STARTUP = "require_cred_before_startup";
public static final int REQUEST_CHANGE_REQUIRE_CRED_FOR_START = 2;
// These switch preferences need special handling since they're not all stored in Settings.
private static final String SWITCH_PREFERENCE_KEYS[] = { KEY_LOCK_AFTER_TIMEOUT,
KEY_VISIBLE_PATTERN, KEY_POWER_INSTANTLY_LOCKS, KEY_REQUIRE_CRED_BEFORE_STARTUP };
private RestrictedListPreference mLockAfter;
private SwitchPreference mVisiblePattern;
private SwitchPreference mPowerButtonInstantlyLocks;
private Preference mOwnerInfoPref;
private LockPatternUtils mLockPatternUtils;
private DevicePolicyManager mDPM;
@Override
protected int getMetricsCategory() {
return MetricsEvent.SECURITY;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mLockPatternUtils = new LockPatternUtils(getContext());
mDPM = getContext().getSystemService(DevicePolicyManager.class);
}
@Override
public void onResume() {
super.onResume();
createPreferenceHierarchy();
final LockPatternUtils lockPatternUtils = mLockPatternUtils;
if (mVisiblePattern != null) {
mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled(
MY_USER_ID));
}
if (mPowerButtonInstantlyLocks != null) {
mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks(
MY_USER_ID));
}
updateOwnerInfo();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
createPreferenceHierarchy();
}
private void createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
root = null;
final int resid = getResIdForLockUnlockSubScreen(getActivity(),
new LockPatternUtils(getContext()));
addPreferencesFromResource(resid);
// lock after preference
mLockAfter = (RestrictedListPreference) findPreference(KEY_LOCK_AFTER_TIMEOUT);
if (mLockAfter != null) {
setupLockAfterPreference();
updateLockAfterPreferenceSummary();
}
// visible pattern
mVisiblePattern = (SwitchPreference) findPreference(KEY_VISIBLE_PATTERN);
// lock instantly on power key press
mPowerButtonInstantlyLocks = (SwitchPreference) findPreference(
KEY_POWER_INSTANTLY_LOCKS);
Preference trustAgentPreference = findPreference(KEY_TRUST_AGENT);
if (mPowerButtonInstantlyLocks != null &&
trustAgentPreference != null &&
trustAgentPreference.getTitle().length() > 0) {
mPowerButtonInstantlyLocks.setSummary(getString(
R.string.lockpattern_settings_power_button_instantly_locks_summary,
trustAgentPreference.getTitle()));
}
mOwnerInfoPref = findPreference(KEY_OWNER_INFO_SETTINGS);
if (mOwnerInfoPref != null) {
mOwnerInfoPref.setEnabled(!mLockPatternUtils.isLockScreenDisabled(MY_USER_ID)
&& !mLockPatternUtils.isDeviceOwnerInfoEnabled());
if (mOwnerInfoPref.isEnabled()) {
mOwnerInfoPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
OwnerInfoSettings.show(SecuritySubSettings.this);
return true;
}
});
}
}
Preference requireCredForStartup = findPreference(KEY_REQUIRE_CRED_BEFORE_STARTUP);
if (requireCredForStartup instanceof SwitchPreference) {
((SwitchPreference) requireCredForStartup).setChecked(
mLockPatternUtils.isCredentialRequiredToDecrypt(false));
if (!canChangeRequireCredentialBeforeStartup(getContext())) {
removePreference(KEY_REQUIRE_CRED_BEFORE_STARTUP);
}
}
for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
if (pref != null) pref.setOnPreferenceChangeListener(this);
}
}
static boolean canChangeRequireCredentialBeforeStartup(Context context) {
DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
return UserManager.get(context).isAdminUser()
&& LockPatternUtils.isDeviceEncryptionEnabled()
&& !dpm.getDoNotAskCredentialsOnBoot();
}
private void setupLockAfterPreference() {
// Compatible with pre-Froyo
long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
mLockAfter.setValue(String.valueOf(currentTimeout));
mLockAfter.setOnPreferenceChangeListener(this);
final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
getActivity());
if (admin != null) {
final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0);
final long displayTimeout = Math.max(0,
Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
if (adminTimeout > 0) {
// This setting is a slave to display timeout when a device policy is enforced.
// As such, maxLockTimeout = adminTimeout - displayTimeout.
// If there isn't enough time, shows "immediately" setting.
disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout), admin);
}
}
}
private void updateLockAfterPreferenceSummary() {
final String summary;
if (mLockAfter.isDisabledByAdmin()) {
summary = getString(R.string.disabled_by_policy_title);
} else {
// Update summary message with current value
long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
final CharSequence[] entries = mLockAfter.getEntries();
final CharSequence[] values = mLockAfter.getEntryValues();
int best = 0;
for (int i = 0; i < values.length; i++) {
if (mLockAfter.isRestrictedForEntry(entries[i])) {
break;
}
long timeout = Long.valueOf(values[i].toString());
if (currentTimeout >= timeout) {
best = i;
}
}
Preference preference = findPreference(KEY_TRUST_AGENT);
if (preference != null && preference.getTitle().length() > 0) {
if (Long.valueOf(values[best].toString()) == 0) {
summary = getString(R.string.lock_immediately_summary_with_exception,
preference.getTitle());
} else {
summary = getString(R.string.lock_after_timeout_summary_with_exception,
entries[best], preference.getTitle());
}
} else {
summary = getString(R.string.lock_after_timeout_summary, entries[best]);
}
}
mLockAfter.setSummary(summary);
}
private void disableUnusableTimeouts(long maxTimeout, EnforcedAdmin admin) {
final CharSequence[] entries = mLockAfter.getEntries();
final CharSequence[] values = mLockAfter.getEntryValues();
long maxTimeoutSelectable = 0;
int maxTimeoutEntryIndex = -1;
for (int i = 0; i < values.length; i++) {
long timeout = Long.parseLong(values[i].toString());
if (timeout > maxTimeout) {
break;
}
maxTimeoutSelectable = timeout;
maxTimeoutEntryIndex = i;
}
// If there are no possible options for the user, then set this preference as
// disabled by admin, otherwise remove the padlock in case it was set earlier.
if (maxTimeoutSelectable == 0) {
mLockAfter.setDisabledByAdmin(admin);
return;
} else {
mLockAfter.setDisabledByAdmin(null);
}
mLockAfter.clearRestrictedItems();
// Set all the entries after the maximum selectable timeout as disabled by admin.
for (int i = maxTimeoutEntryIndex + 1; i < values.length; i++) {
mLockAfter.addRestrictedItem(
new RestrictedItem(entries[i], values[i], admin));
}
final int userPreference = Integer.valueOf(mLockAfter.getValue());
if (userPreference <= maxTimeout) {
mLockAfter.setValue(String.valueOf(userPreference));
} else if (maxTimeoutSelectable == maxTimeout) {
mLockAfter.setValue(String.valueOf(maxTimeout));
} else {
// There will be no highlighted selection since nothing in the list matches
// maxTimeout. The user can still select anything less than maxTimeout.
// TODO: maybe append maxTimeout to the list and mark selected.
}
}
public void updateOwnerInfo() {
if (mOwnerInfoPref != null) {
if (mLockPatternUtils.isDeviceOwnerInfoEnabled()) {
mOwnerInfoPref.setSummary(R.string.disabled_by_administrator_summary);
} else {
mOwnerInfoPref.setSummary(mLockPatternUtils.isOwnerInfoEnabled(MY_USER_ID)
? mLockPatternUtils.getOwnerInfo(MY_USER_ID)
: getString(R.string.owner_info_settings_summary));
}
}
}
private static int getResIdForLockUnlockSubScreen(Context context,
LockPatternUtils lockPatternUtils) {
if (lockPatternUtils.isSecure(MY_USER_ID)) {
switch (lockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
return R.xml.security_settings_pattern_sub;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
return R.xml.security_settings_pin_sub;
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
return R.xml.security_settings_password_sub;
}
} else if (!lockPatternUtils.isLockScreenDisabled(MY_USER_ID)) {
return R.xml.security_settings_slide_sub;
}
return 0;
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
String key = preference.getKey();
if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) {
mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value, MY_USER_ID);
} else if (KEY_LOCK_AFTER_TIMEOUT.equals(key)) {
int timeout = Integer.parseInt((String) value);
try {
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
} catch (NumberFormatException e) {
Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e);
}
updateLockAfterPreferenceSummary();
} else if (KEY_VISIBLE_PATTERN.equals(key)) {
mLockPatternUtils.setVisiblePatternEnabled((Boolean) value, MY_USER_ID);
} else if (KEY_REQUIRE_CRED_BEFORE_STARTUP.equals(key)) {
Bundle extras = new Bundle();
extras.putBoolean(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, true);
startFragment(this,
"com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
R.string.lock_settings_picker_title, REQUEST_CHANGE_REQUIRE_CRED_FOR_START,
extras);
return false;
}
return true;
}
}
}