Merge "Work Profile Passphrase Setting"
This commit is contained in:
committed by
Android (Google) Code Review
commit
13c52fa850
@@ -3015,6 +3015,12 @@
|
||||
<!-- Displayed when user launches a widget configuration activity that was uninstalled -->
|
||||
<string name="activity_not_found">Application is not installed on your phone.</string>
|
||||
|
||||
<!-- Profile Lock settings -->
|
||||
<!-- Security & location settings screen, header for profile specific section -->
|
||||
<string name="lock_settings_profile_title">Work profile</string>
|
||||
<!-- Security & location settings screen, setting option name -->
|
||||
<string name="lock_settings_profile_label">Work profile security</string>
|
||||
|
||||
<!-- Applications Settings --> <skip />
|
||||
<!-- Applications settings screen, setting option name for the user to go to the screen to manage installed applications -->
|
||||
<string name="manageapplications_settings_title">Manage apps</string>
|
||||
@@ -5562,6 +5568,7 @@
|
||||
<string name="keywords_ignore_optimizations">ignore optimizations, doze, app standby</string>
|
||||
<string name="keywords_color_mode">vibrant, RGB, sRGB, color, natural, standard</string>
|
||||
<string name="keywords_lockscreen">slide to unlock, password, pattern, PIN</string>
|
||||
<string name="keywords_profile_challenge">work challenge, work, profile</string>
|
||||
|
||||
<!-- NFC Wi-Fi pairing/setup strings-->
|
||||
|
||||
|
||||
20
res/xml/profile_challenge_settings.xml
Normal file
20
res/xml/profile_challenge_settings.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2008 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"
|
||||
android:title="@string/lock_settings_profile_label">
|
||||
|
||||
</PreferenceScreen>
|
||||
33
res/xml/security_settings_profile.xml
Normal file
33
res/xml/security_settings_profile.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?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/lock_settings_picker_title">
|
||||
|
||||
<PreferenceCategory
|
||||
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>
|
||||
@@ -48,7 +48,6 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
|
||||
public class ChooseLockGeneric extends SettingsActivity {
|
||||
public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
|
||||
public static final String KEY_USER_ID = "user_id";
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
@@ -369,6 +368,10 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
visible = false;
|
||||
}
|
||||
} else if (KEY_UNLOCK_SET_NONE.equals(key)) {
|
||||
if (mUserId != UserHandle.myUserId()) {
|
||||
// Swipe doesn't make sense for profiles.
|
||||
visible = false;
|
||||
}
|
||||
enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
} else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
|
||||
enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
|
||||
@@ -87,7 +87,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
boolean confirmCredentials, int userId) {
|
||||
Intent intent = createIntent(context, quality, minLength, maxLength,
|
||||
requirePasswordToDecrypt, confirmCredentials);
|
||||
intent.putExtra(ChooseLockGeneric.KEY_USER_ID, userId);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
int maxLength, boolean requirePasswordToDecrypt, String password, int userId) {
|
||||
Intent intent = createIntent(context, quality, minLength, maxLength,
|
||||
requirePasswordToDecrypt, password);
|
||||
intent.putExtra(ChooseLockGeneric.KEY_USER_ID, userId);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
int maxLength, boolean requirePasswordToDecrypt, long challenge, int userId) {
|
||||
Intent intent = createIntent(context, quality, minLength, maxLength,
|
||||
requirePasswordToDecrypt, challenge);
|
||||
intent.putExtra(ChooseLockGeneric.KEY_USER_ID, userId);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
intent.putExtra("key_lock_method", "pattern");
|
||||
intent.putExtra(ChooseLockGeneric.CONFIRM_CREDENTIALS, confirmCredentials);
|
||||
intent.putExtra(EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, requirePassword);
|
||||
intent.putExtra(ChooseLockGeneric.KEY_USER_ID, userId);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ public final class ChooseLockSettingsHelper {
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
|
||||
intent.putExtra(ChooseLockGeneric.KEY_USER_ID, userId);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
intent.setClassName(ConfirmDeviceCredentialBaseFragment.PACKAGE, activityClass.getName());
|
||||
if (external) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
|
||||
|
||||
193
src/com/android/settings/ProfileChallengePreferenceFragment.java
Normal file
193
src/com/android/settings/ProfileChallengePreferenceFragment.java
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
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.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 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 int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
|
||||
|
||||
// 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 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;
|
||||
}
|
||||
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 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
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;
|
||||
@@ -79,6 +80,7 @@ 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";
|
||||
@@ -138,6 +140,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
private Intent mTrustAgentClickIntent;
|
||||
private Preference mOwnerInfoPref;
|
||||
|
||||
private int mProfileChallengeUserId;
|
||||
|
||||
@Override
|
||||
protected int getMetricsCategory() {
|
||||
return MetricsLogger.SECURITY;
|
||||
@@ -209,6 +213,20 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils);
|
||||
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 (LockPatternUtils.isSeparateWorkChallengeEnabled()) {
|
||||
addPreferencesFromResource(R.xml.security_settings_profile);
|
||||
}
|
||||
}
|
||||
|
||||
// Add options for device encryption
|
||||
mIsAdmin = mUm.isAdminUser();
|
||||
|
||||
@@ -655,6 +673,11 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
|
||||
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
|
||||
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
||||
} 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);
|
||||
} else if (KEY_TRUST_AGENT.equals(key)) {
|
||||
ChooseLockSettingsHelper helper =
|
||||
new ChooseLockSettingsHelper(this.getActivity(), this);
|
||||
@@ -752,6 +775,13 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
result.add(sir);
|
||||
|
||||
final UserManager um = UserManager.get(context);
|
||||
boolean hasChildProfile = um.getProfiles(UserHandle.myUserId()).size() > 1;
|
||||
if (hasChildProfile && LockPatternUtils.isSeparateWorkChallengeEnabled()) {
|
||||
sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.security_settings_profile;
|
||||
result.add(sir);
|
||||
}
|
||||
|
||||
if (um.isAdminUser()) {
|
||||
DevicePolicyManager dpm = (DevicePolicyManager)
|
||||
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
|
||||
@@ -335,6 +335,17 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
}
|
||||
};
|
||||
|
||||
private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action.equals(Intent.ACTION_USER_ADDED)
|
||||
|| action.equals(Intent.ACTION_USER_REMOVED)) {
|
||||
Index.getInstance(getApplicationContext()).update();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
|
||||
new DynamicIndexableContentMonitor();
|
||||
|
||||
@@ -752,6 +763,8 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
mDevelopmentPreferencesListener);
|
||||
|
||||
registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
|
||||
registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
|
||||
|
||||
mDynamicIndexableContentMonitor.register(this);
|
||||
|
||||
|
||||
@@ -1026,7 +1026,7 @@ public final class Utils {
|
||||
if (bundle == null) {
|
||||
return getEffectiveUserId(context);
|
||||
}
|
||||
int userId = bundle.getInt(ChooseLockGeneric.KEY_USER_ID, UserHandle.myUserId());
|
||||
int userId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId());
|
||||
return getSameOwnerUserId(context, userId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user