Fork SecuritySettings page and hide behind a feature flag.

Bug: 32953042
Test: robotests
Change-Id: Ibbb4221eef87f09ccd024146517707680180a100
This commit is contained in:
Fan Zhang
2017-12-22 09:59:37 -08:00
parent ce3633be80
commit f314494f32
12 changed files with 1154 additions and 5 deletions

View File

@@ -1287,6 +1287,28 @@
android:value="true" /> android:value="true" />
</activity> </activity>
<!-- TODO(32953042) Merge with Settings$SecuritySettingsActivity -->
<activity android:name="Settings$SecuritySettingsActivityV2"
android:label="@string/security_settings_title"
android:icon="@drawable/ic_settings_security"
android:enabled="false"
android:configChanges="orientation|keyboardHidden|screenSize"
android:taskAffinity=""
android:parentActivityName="Settings">
<intent-filter android:priority="-1">
<action android:name="android.settings.SECURITY_SETTINGS" />
<action android:name="android.credentials.UNLOCK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter android:priority="4">
<action android:name="com.android.settings.action.SETTINGS" />
</intent-filter>
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.homepage" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.security.SecuritySettingsV2" />
</activity>
<activity android:name="MonitoringCertInfoActivity" <activity android:name="MonitoringCertInfoActivity"
android:label="" android:label=""
android:theme="@style/Transparent" android:theme="@style/Transparent"

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="security_dashboard_page"
android:title="@string/security_settings_title"
settings:initialExpandedChildrenCount="9">
<!-- security_settings_status.xml -->
<PreferenceCategory
android:key="security_status"
android:title="@string/security_status_title" />
<!-- TODO Need security section -->
<!-- security_settings_misc.xml -->
<PreferenceCategory
android:key="security_settings_misc_category"
android:title="@string/security_passwords_title">
<Preference
android:key="location"
android:title="@string/location_settings_title"
android:fragment="com.android.settings.location.LocationSettings">
</Preference>
<SwitchPreference
android:key="show_password"
android:title="@string/show_password"
android:summary="@string/show_password_summary"/>
</PreferenceCategory>
<PreferenceCategory
android:key="security_settings_device_admin_category">
<Preference android:key="manage_device_admin"
android:title="@string/manage_device_admin"
android:persistent="false"
android:fragment="com.android.settings.DeviceAdminSettings"/>
<Preference android:key="enterprise_privacy"
android:title="@string/enterprise_privacy_settings"
android:persistent="false"
android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"/>
</PreferenceCategory>
<Preference android:key="sim_lock_settings"
android:title="@string/sim_lock_settings_category"
android:persistent="false">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.Settings$IccLockSettingsActivity"/>
</Preference>
<Preference
android:key="encryption_and_credential"
android:title="@string/encryption_and_credential_settings_title"
android:summary="@string/encryption_and_credential_settings_summary"
android:fragment="com.android.settings.security.EncryptionAndCredential"/>
<Preference android:key="manage_trust_agents"
android:title="@string/manage_trust_agents"
android:persistent="false"
android:fragment="com.android.settings.security.trustagent.TrustAgentSettings"/>
<Preference
android:key="screen_pinning_settings"
android:title="@string/screen_pinning_title"
android:summary="@string/switch_off_text"
android:fragment="com.android.settings.security.ScreenPinningSettings"/>
<Preference android:key="security_misc_usage_access"
android:title="@string/usage_access_title"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications">
<extra
android:name="classname"
android:value="com.android.settings.Settings$UsageAccessSettingsActivity" />
</Preference>
</PreferenceScreen>

View File

@@ -68,6 +68,7 @@ public class Settings extends SettingsActivity {
public static class AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityContrastSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ } public static class AccessibilityDaltonizerSettingsActivity extends SettingsActivity { /* empty */ }
public static class SecuritySettingsActivity extends SettingsActivity { /* empty */ } public static class SecuritySettingsActivity extends SettingsActivity { /* empty */ }
public static class SecuritySettingsActivityV2 extends SettingsActivity { /* empty */ }
public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ } public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }
public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ } public static class PrivacySettingsActivity extends SettingsActivity { /* empty */ }

View File

@@ -751,6 +751,7 @@ public class SettingsActivity extends SettingsDrawerActivity
PackageManager pm = getPackageManager(); PackageManager pm = getPackageManager();
final UserManager um = UserManager.get(this); final UserManager um = UserManager.get(this);
final boolean isAdmin = um.isAdminUser(); final boolean isAdmin = um.isAdminUser();
final FeatureFactory featureFactory = FeatureFactory.getFactory(this);
boolean somethingChanged = false; boolean somethingChanged = false;
String packageName = getPackageName(); String packageName = getPackageName();
somethingChanged = setTileEnabled( somethingChanged = setTileEnabled(
@@ -805,12 +806,26 @@ public class SettingsActivity extends SettingsDrawerActivity
!isConnectedDeviceV2Enabled && !UserManager.isDeviceInDemoMode(this) /* enabled */, !isConnectedDeviceV2Enabled && !UserManager.isDeviceInDemoMode(this) /* enabled */,
isAdmin) || somethingChanged; isAdmin) || somethingChanged;
final boolean isSecurityV2Enabled = featureFactory.getSecurityFeatureProvider()
.isSecuritySettingsV2Enabled(this);
// Enable new security page if v2 enabled
somethingChanged = setTileEnabled(
new ComponentName(packageName,Settings.SecuritySettingsActivityV2.class.getName()),
isSecurityV2Enabled,
isAdmin) || somethingChanged;
// Enable old security page if v2 disabled
somethingChanged = setTileEnabled(
new ComponentName(packageName,Settings.SecuritySettingsActivity.class.getName()),
!isSecurityV2Enabled,
isAdmin) || somethingChanged;
somethingChanged = setTileEnabled(new ComponentName(packageName, somethingChanged = setTileEnabled(new ComponentName(packageName,
Settings.SimSettingsActivity.class.getName()), Settings.SimSettingsActivity.class.getName()),
Utils.showSimCardTile(this), isAdmin) Utils.showSimCardTile(this), isAdmin)
|| somethingChanged; || somethingChanged;
final boolean isBatterySettingsV2Enabled = FeatureFactory.getFactory(this) final boolean isBatterySettingsV2Enabled = featureFactory
.getPowerUsageFeatureProvider(this) .getPowerUsageFeatureProvider(this)
.isBatteryV2Enabled(); .isBatteryV2Enabled();
// Enable new battery page if v2 enabled // Enable new battery page if v2 enabled

View File

@@ -26,4 +26,5 @@ public class FeatureFlags {
public static final String CONNECTED_DEVICE_V2 = "settings_connected_device_v2"; public static final String CONNECTED_DEVICE_V2 = "settings_connected_device_v2";
public static final String BATTERY_SETTINGS_V2 = "settings_battery_v2"; public static final String BATTERY_SETTINGS_V2 = "settings_battery_v2";
public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list"; public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
public static final String SECURITY_SETTINGS_V2 = "settings_security_settings_v2";
} }

View File

@@ -115,6 +115,7 @@ import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.security.CryptKeeperSettings; import com.android.settings.security.CryptKeeperSettings;
import com.android.settings.security.LockscreenDashboardFragment; import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings; import com.android.settings.security.SecuritySettings;
import com.android.settings.security.SecuritySettingsV2;
import com.android.settings.sim.SimSettings; import com.android.settings.sim.SimSettings;
import com.android.settings.support.SupportDashboardActivity; import com.android.settings.support.SupportDashboardActivity;
import com.android.settings.system.ResetDashboardFragment; import com.android.settings.system.ResetDashboardFragment;
@@ -163,6 +164,7 @@ public class SettingsGateway {
NotificationStation.class.getName(), NotificationStation.class.getName(),
LocationSettings.class.getName(), LocationSettings.class.getName(),
SecuritySettings.class.getName(), SecuritySettings.class.getName(),
SecuritySettingsV2.class.getName(),
UsageAccessDetails.class.getName(), UsageAccessDetails.class.getName(),
PrivacySettings.class.getName(), PrivacySettings.class.getName(),
DeviceAdminSettings.class.getName(), DeviceAdminSettings.class.getName(),

View File

@@ -33,7 +33,7 @@ import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.notification.ConfigureNotificationSettings; import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings; import com.android.settings.notification.SoundSettings;
import com.android.settings.security.LockscreenDashboardFragment; import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings; import com.android.settings.security.SecuritySettingsV2;
import com.android.settings.system.SystemDashboardFragment; import com.android.settings.system.SystemDashboardFragment;
import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryKey;
@@ -77,7 +77,7 @@ public class DashboardFragmentRegistry {
CategoryKey.CATEGORY_SOUND); CategoryKey.CATEGORY_SOUND);
PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(), PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
CategoryKey.CATEGORY_STORAGE); CategoryKey.CATEGORY_STORAGE);
PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettings.class.getName(), PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettingsV2.class.getName(),
CategoryKey.CATEGORY_SECURITY); CategoryKey.CATEGORY_SECURITY);
PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(), PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(),
CategoryKey.CATEGORY_ACCOUNT_DETAIL); CategoryKey.CATEGORY_ACCOUNT_DETAIL);

View File

@@ -18,7 +18,9 @@ package com.android.settings.security;
import android.content.Context; import android.content.Context;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.util.FeatureFlagUtils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.security.trustagent.TrustAgentManager; import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.DashboardCategory;
@@ -26,6 +28,10 @@ import com.android.settingslib.drawer.DashboardCategory;
/** FeatureProvider for security. */ /** FeatureProvider for security. */
public interface SecurityFeatureProvider { public interface SecurityFeatureProvider {
default boolean isSecuritySettingsV2Enabled(Context context) {
return FeatureFlagUtils.isEnabled(context, FeatureFlags.SECURITY_SETTINGS_V2);
}
/** Update preferences with data from associated tiles. */ /** Update preferences with data from associated tiles. */
void updatePreferences(Context context, PreferenceScreen preferenceScreen, void updatePreferences(Context context, PreferenceScreen preferenceScreen,
DashboardCategory dashboardCategory); DashboardCategory dashboardCategory);

View File

@@ -0,0 +1,917 @@
package com.android.settings.security;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.enterprise.EnterprisePrivacyPreferenceController;
import com.android.settings.enterprise.ManageDeviceAdminPreferenceController;
import com.android.settings.fingerprint.FingerprintSettings;
import com.android.settings.location.LocationPreferenceController;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ManagedLockPasswordProvider;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settings.widget.GearPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.drawer.CategoryKey;
import java.util.ArrayList;
import java.util.List;
public class SecuritySettingsV2 extends DashboardFragment
implements Preference.OnPreferenceChangeListener,
GearPreference.OnGearClickListener {
private static final String TAG = "SecuritySettingsV2";
private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent";
// 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 = "unlock_set_or_change_profile";
private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
private static final String KEY_SECURITY_CATEGORY = "security_category";
@VisibleForTesting
static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
private static final String KEY_UNIFICATION = "unification";
@VisibleForTesting
static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
private static final String KEY_ENCRYPTION_AND_CREDENTIALS = "encryption_and_credential";
private static final String KEY_LOCATION_SCANNING = "location_scanning";
private static final String KEY_LOCATION = "location";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
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 int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
private static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
// Misc Settings
private static final String KEY_SIM_LOCK = "sim_lock_settings";
private static final String KEY_SHOW_PASSWORD = "show_password";
private static final String KEY_TRUST_AGENT = "trust_agent";
private static final String KEY_SCREEN_PINNING = "screen_pinning_settings";
// Security status
private static final String KEY_SECURITY_STATUS = "security_status";
private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_";
// Device management settings
private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
private static final String KEY_MANAGE_DEVICE_ADMIN = "manage_device_admin";
// These switch preferences need special handling since they're not all stored in Settings.
private static final String SWITCH_PREFERENCE_KEYS[] = {
KEY_SHOW_PASSWORD, KEY_UNIFICATION, KEY_VISIBLE_PATTERN_PROFILE
};
private static final int MY_USER_ID = UserHandle.myUserId();
private DashboardFeatureProvider mDashboardFeatureProvider;
private DevicePolicyManager mDPM;
private SecurityFeatureProvider mSecurityFeatureProvider;
private TrustAgentManager mTrustAgentManager;
private SubscriptionManager mSubscriptionManager;
private UserManager mUm;
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private LockPatternUtils mLockPatternUtils;
private ManagedLockPasswordProvider mManagedPasswordProvider;
private SwitchPreference mVisiblePatternProfile;
private RestrictedSwitchPreference mUnifyProfile;
private SwitchPreference mShowPassword;
private boolean mIsAdmin;
private Intent mTrustAgentClickIntent;
private int mProfileChallengeUserId;
private String mCurrentDevicePassword;
private String mCurrentProfilePassword;
private LocationPreferenceController mLocationController;
private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
private LockScreenNotificationPreferenceController mLockScreenNotificationPreferenceController;
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.SECURITY;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mLocationController = new LocationPreferenceController(context, getLifecycle());
mSubscriptionManager = SubscriptionManager.from(context);
mLockPatternUtils = new LockPatternUtils(context);
mManagedPasswordProvider = ManagedLockPasswordProvider.get(context, MY_USER_ID);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mUm = UserManager.get(context);
mDashboardFeatureProvider = FeatureFactory.getFactory(context)
.getDashboardFeatureProvider(context);
mSecurityFeatureProvider = FeatureFactory.getFactory(context).getSecurityFeatureProvider();
mTrustAgentManager = mSecurityFeatureProvider.getTrustAgentManager();
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.security_settings_v2;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
mManageDeviceAdminPreferenceController
= new ManageDeviceAdminPreferenceController(context);
mEnterprisePrivacyPreferenceController
= new EnterprisePrivacyPreferenceController(context);
mLockScreenNotificationPreferenceController
= new LockScreenNotificationPreferenceController(context);
return null;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
if (savedInstanceState != null
&& savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) {
mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT);
}
}
private static int getResIdForLockUnlockScreen(LockPatternUtils lockPatternUtils,
ManagedLockPasswordProvider managedPasswordProvider, int userId) {
final boolean isMyUser = userId == MY_USER_ID;
int resid = 0;
if (!lockPatternUtils.isSecure(userId)) {
if (!isMyUser) {
resid = R.xml.security_settings_lockscreen_profile;
} else if (lockPatternUtils.isLockScreenDisabled(userId)) {
resid = R.xml.security_settings_lockscreen;
} else {
resid = R.xml.security_settings_chooser;
}
} else {
switch (lockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
resid = isMyUser ? R.xml.security_settings_pattern
: R.xml.security_settings_pattern_profile;
break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
resid = isMyUser ? R.xml.security_settings_pin
: R.xml.security_settings_pin_profile;
break;
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
resid = isMyUser ? R.xml.security_settings_password
: R.xml.security_settings_password_profile;
break;
case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
resid = managedPasswordProvider.getResIdForLockUnlockScreen(!isMyUser);
break;
}
}
return resid;
}
/**
* Important!
*
* Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the
* logic or adding/removing preferences here.
*/
private PreferenceScreen createPreferenceHierarchy() {
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
addPreferencesFromResource(R.xml.security_settings_v2);
root = getPreferenceScreen();
// Add options for lock/unlock screen
final int resid = getResIdForLockUnlockScreen(mLockPatternUtils,
mManagedPasswordProvider, MY_USER_ID);
addPreferencesFromResource(resid);
// DO or PO installed in the user may disallow to change password.
disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, MY_USER_ID);
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
if (mProfileChallengeUserId != UserHandle.USER_NULL
&& mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
addPreferencesFromResource(R.xml.security_settings_profile);
addPreferencesFromResource(R.xml.security_settings_unification);
final int profileResid = getResIdForLockUnlockScreen(mLockPatternUtils,
mManagedPasswordProvider, mProfileChallengeUserId);
addPreferencesFromResource(profileResid);
maybeAddFingerprintPreference(root, mProfileChallengeUserId);
if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
final Preference lockPreference =
root.findPreference(KEY_UNLOCK_SET_OR_CHANGE_PROFILE);
final String summary = getContext().getString(
R.string.lock_settings_profile_unified_summary);
lockPreference.setSummary(summary);
lockPreference.setEnabled(false);
// PO may disallow to change password for the profile, but screen lock and managed
// profile's lock is the same. Disable main "Screen lock" menu.
disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, mProfileChallengeUserId);
} else {
// PO may disallow to change profile password, and the profile's password is
// separated from screen lock password. Disable profile specific "Screen lock" menu.
disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE_PROFILE,
mProfileChallengeUserId);
}
}
Preference unlockSetOrChange = findPreference(KEY_UNLOCK_SET_OR_CHANGE);
if (unlockSetOrChange instanceof GearPreference) {
((GearPreference) unlockSetOrChange).setOnGearClickListener(this);
}
mIsAdmin = mUm.isAdminUser();
// Fingerprint and trust agents
int numberOfTrustAgent = 0;
PreferenceGroup securityCategory = (PreferenceGroup)
root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null) {
maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
numberOfTrustAgent = addTrustAgentSettings(securityCategory);
setLockscreenPreferencesSummary(securityCategory);
}
mVisiblePatternProfile =
(SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
mUnifyProfile = (RestrictedSwitchPreference) root.findPreference(KEY_UNIFICATION);
// Do not display SIM lock for devices without an Icc card
TelephonyManager tm = TelephonyManager.getDefault();
CarrierConfigManager cfgMgr = (CarrierConfigManager)
getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE);
PersistableBundle b = cfgMgr.getConfig();
if (!mIsAdmin || !isSimIccReady() ||
b.getBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL)) {
root.removePreference(root.findPreference(KEY_SIM_LOCK));
} else {
// Disable SIM lock if there is no ready SIM card.
root.findPreference(KEY_SIM_LOCK).setEnabled(isSimReady());
}
if (Settings.System.getInt(getContentResolver(),
Settings.System.LOCK_TO_APP_ENABLED, 0) != 0) {
root.findPreference(KEY_SCREEN_PINNING).setSummary(
getResources().getString(R.string.switch_on_text));
}
// Encryption status of device
if (LockPatternUtils.isDeviceEncryptionEnabled()) {
root.findPreference(KEY_ENCRYPTION_AND_CREDENTIALS).setSummary(
R.string.encryption_and_credential_settings_summary);
} else {
root.findPreference(KEY_ENCRYPTION_AND_CREDENTIALS).setSummary(
R.string.summary_placeholder);
}
// Show password
mShowPassword = (SwitchPreference) root.findPreference(KEY_SHOW_PASSWORD);
// Credential storage
final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
// Advanced Security features
initTrustAgentPreference(root, numberOfTrustAgent);
PreferenceGroup securityStatusPreferenceGroup =
(PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS);
final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
getActivity(), getPrefContext(), getMetricsCategory(),
CategoryKey.CATEGORY_SECURITY);
int numSecurityStatusPrefs = 0;
if (tilePrefs != null && !tilePrefs.isEmpty()) {
for (Preference preference : tilePrefs) {
if (!TextUtils.isEmpty(preference.getKey())
&& preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) {
// Injected security status settings are placed under the Security status
// category.
securityStatusPreferenceGroup.addPreference(preference);
numSecurityStatusPrefs++;
} else {
// Other injected settings are placed under the Security preference screen.
root.addPreference(preference);
}
}
}
if (numSecurityStatusPrefs == 0) {
root.removePreference(securityStatusPreferenceGroup);
} else if (numSecurityStatusPrefs > 0) {
// Update preference data with tile data. Security feature provider only updates the
// data if it actually needs to be changed.
mSecurityFeatureProvider.updatePreferences(getActivity(), root,
mDashboardFeatureProvider.getTilesForCategory(
CategoryKey.CATEGORY_SECURITY));
}
for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
if (pref != null) pref.setOnPreferenceChangeListener(this);
}
mLocationController.displayPreference(root);
mManageDeviceAdminPreferenceController.updateState(
root.findPreference(KEY_MANAGE_DEVICE_ADMIN));
mEnterprisePrivacyPreferenceController.displayPreference(root);
final Preference enterprisePrivacyPreference = root.findPreference(
mEnterprisePrivacyPreferenceController.getPreferenceKey());
mEnterprisePrivacyPreferenceController.updateState(enterprisePrivacyPreference);
return root;
}
@VisibleForTesting
void initTrustAgentPreference(PreferenceScreen root, int numberOfTrustAgent) {
Preference manageAgents = root.findPreference(KEY_MANAGE_TRUST_AGENTS);
if (manageAgents != null) {
if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
manageAgents.setEnabled(false);
manageAgents.setSummary(R.string.disabled_because_no_backup_security);
} else if (numberOfTrustAgent > 0) {
manageAgents.setSummary(getActivity().getResources().getQuantityString(
R.plurals.manage_trust_agents_summary_on,
numberOfTrustAgent, numberOfTrustAgent));
} else {
manageAgents.setSummary(R.string.manage_trust_agents_summary);
}
}
}
@VisibleForTesting
void setLockscreenPreferencesSummary(PreferenceGroup group) {
final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
if (lockscreenPreferences != null) {
lockscreenPreferences.setSummary(
mLockScreenNotificationPreferenceController.getSummaryResource());
}
}
/*
* Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
* The preference must be a RestrictedPreference.
*/
private void disableIfPasswordQualityManaged(String preferenceKey, int userId) {
final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
getActivity(), userId);
if (admin != null && mDPM.getPasswordQuality(admin.component, userId) ==
DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
final RestrictedPreference pref =
(RestrictedPreference) getPreferenceScreen().findPreference(preferenceKey);
pref.setDisabledByAdmin(admin);
}
}
private void maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId) {
Preference fingerprintPreference =
FingerprintSettings.getFingerprintPreferenceForUser(
securityCategory.getContext(), userId);
if (fingerprintPreference != null) {
securityCategory.addPreference(fingerprintPreference);
}
}
// Return the number of trust agents being added
private int addTrustAgentSettings(PreferenceGroup securityCategory) {
final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
final List<TrustAgentManager.TrustAgentComponentInfo> agents = mTrustAgentManager.getActiveTrustAgents(
getActivity(), mLockPatternUtils);
for (TrustAgentManager.TrustAgentComponentInfo agent : agents) {
final RestrictedPreference trustAgentPreference =
new RestrictedPreference(securityCategory.getContext());
trustAgentPreference.setKey(KEY_TRUST_AGENT);
trustAgentPreference.setTitle(agent.title);
trustAgentPreference.setSummary(agent.summary);
// Create intent for this preference.
Intent intent = new Intent();
intent.setComponent(agent.componentName);
intent.setAction(Intent.ACTION_MAIN);
trustAgentPreference.setIntent(intent);
// Add preference to the settings menu.
securityCategory.addPreference(trustAgentPreference);
trustAgentPreference.setDisabledByAdmin(agent.admin);
if (!trustAgentPreference.isDisabledByAdmin() && !hasSecurity) {
trustAgentPreference.setEnabled(false);
trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security);
}
}
return agents.size();
}
/* Return true if a there is a Slot that has Icc.
*/
private boolean isSimIccReady() {
TelephonyManager tm = TelephonyManager.getDefault();
final List<SubscriptionInfo> subInfoList =
mSubscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList != null) {
for (SubscriptionInfo subInfo : subInfoList) {
if (tm.hasIccCard(subInfo.getSimSlotIndex())) {
return true;
}
}
}
return false;
}
/* Return true if a SIM is ready for locking.
* TODO: consider adding to TelephonyManager or SubscritpionManasger.
*/
private boolean isSimReady() {
final List<SubscriptionInfo> subInfoList =
mSubscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList != null) {
for (SubscriptionInfo subInfo : subInfoList) {
final int simState = TelephonyManager.getDefault()
.getSimState(subInfo.getSimSlotIndex());
if ((simState != TelephonyManager.SIM_STATE_ABSENT) &&
(simState != TelephonyManager.SIM_STATE_UNKNOWN)) {
return true;
}
}
}
return false;
}
@Override
public void onGearClick(GearPreference p) {
if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
startFragment(this, ScreenLockSettings.class.getName(), 0, 0, null);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mTrustAgentClickIntent != null) {
outState.putParcelable(TRUST_AGENT_CLICK_INTENT, mTrustAgentClickIntent);
}
}
@Override
public void onResume() {
super.onResume();
// Make sure we reload the preference hierarchy since some of these settings
// depend on others...
createPreferenceHierarchy();
if (mVisiblePatternProfile != null) {
mVisiblePatternProfile.setChecked(mLockPatternUtils.isVisiblePatternEnabled(
mProfileChallengeUserId));
}
updateUnificationPreference();
if (mShowPassword != null) {
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
}
mLocationController.updateSummary();
}
@VisibleForTesting
void updateUnificationPreference() {
if (mUnifyProfile != null) {
final boolean separate =
mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
mUnifyProfile.setChecked(!separate);
if (separate) {
mUnifyProfile.setDisabledByAdmin(RestrictedLockUtils.checkIfRestrictionEnforced(
getContext(), UserManager.DISALLOW_UNIFIED_PASSWORD,
mProfileChallengeUserId));
}
}
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
final String key = preference.getKey();
if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
// TODO(b/35930129): Remove once existing password can be passed into vold directly.
// Currently we need this logic to ensure that the QUIET_MODE is off for any work
// profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
// able to complete the operation due to the lack of (old) encryption key.
if (mProfileChallengeUserId != UserHandle.USER_NULL
&& !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
&& StorageManager.isFileEncryptedNativeOnly()) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
}
startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
} else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
} else if (KEY_TRUST_AGENT.equals(key)) {
ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(this.getActivity(), this);
mTrustAgentClickIntent = preference.getIntent();
boolean confirmationLaunched = helper.launchConfirmationActivity(
CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
if (!confirmationLaunched&& mTrustAgentClickIntent != null) {
// If this returns false, it means no password confirmation is required.
startActivity(mTrustAgentClickIntent);
mTrustAgentClickIntent = null;
}
} else {
// If we didn't handle it, let preferences handle it.
return super.onPreferenceTreeClick(preference);
}
return true;
}
/**
* see confirmPatternThenDisableAndClear
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) {
if (mTrustAgentClickIntent != null) {
startActivity(mTrustAgentClickIntent);
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;
} else if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
ununifyLocks();
return;
}
createPreferenceHierarchy();
}
void launchConfirmDeviceLockForUnification() {
final String title = getActivity().getString(
R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
launchConfirmProfileLockForUnification();
}
}
private void launchConfirmProfileLockForUnification() {
final String title = getActivity().getString(
R.string.unlock_set_unlock_launch_picker_title_profile);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
unifyLocks();
createPreferenceHierarchy();
}
}
private void unifyLocks() {
int profileQuality =
mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.stringToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID);
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword,
profileQuality, MY_USER_ID);
}
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
mCurrentProfilePassword);
final boolean profilePatternVisibility =
mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
mCurrentDevicePassword = null;
mCurrentProfilePassword = null;
}
void unifyUncompliantLocks() {
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
mCurrentProfilePassword);
startFragment(this, ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
}
private void ununifyLocks() {
Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
startFragment(this,
ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
R.string.lock_settings_picker_title_profile,
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
boolean result = true;
final String key = preference.getKey();
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
} else if (KEY_UNIFICATION.equals(key)) {
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
mProfileChallengeUserId)) {
return false;
}
if ((Boolean) value) {
final boolean compliantForDevice =
(mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
mProfileChallengeUserId));
UnificationConfirmationDialog dialog =
UnificationConfirmationDialog.newIntance(compliantForDevice);
dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
} else {
final String title = getActivity().getString(
R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(getActivity(), this);
if(!helper.launchConfirmationActivity(
UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
ununifyLocks();
}
}
} 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);
}
return result;
}
@Override
public int getHelpResource() {
return R.string.help_url_security;
}
/**
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new SecuritySearchIndexProvider();
private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
// TODO (b/68001777) Refactor indexing to include all XML and block other settings.
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final List<SearchIndexableResource> index = new ArrayList<>();
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
final ManagedLockPasswordProvider managedPasswordProvider =
ManagedLockPasswordProvider.get(context, MY_USER_ID);
final DevicePolicyManager dpm = (DevicePolicyManager)
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
final UserManager um = UserManager.get(context);
final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
// To add option for unlock screen, user's password must not be managed and
// must not be unified with managed profile, whose password is managed.
if (!isPasswordManaged(MY_USER_ID, context, dpm)
&& (profileUserId == UserHandle.USER_NULL
|| lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
|| !isPasswordManaged(profileUserId, context, dpm))) {
// Add options for lock/unlock screen
final int resId = getResIdForLockUnlockScreen(lockPatternUtils,
managedPasswordProvider, MY_USER_ID);
index.add(getSearchResource(context, resId));
}
if (profileUserId != UserHandle.USER_NULL
&& lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
&& !isPasswordManaged(profileUserId, context, dpm)) {
index.add(getSearchResource(context, getResIdForLockUnlockScreen(
lockPatternUtils, managedPasswordProvider, profileUserId)));
}
// Append the rest of the settings
index.add(getSearchResource(context, R.xml.security_settings_misc));
return index;
}
private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = xmlResId;
return sir;
}
private boolean isPasswordManaged(int userId, Context context, DevicePolicyManager dpm) {
final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
context, userId);
return admin != null && dpm.getPasswordQuality(admin.component, userId) ==
DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
}
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
final Resources res = context.getResources();
final String screenTitle = res.getString(R.string.security_settings_title);
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = screenTitle;
data.key = "security_settings_screen";
data.screenTitle = screenTitle;
result.add(data);
final UserManager um = UserManager.get(context);
// Fingerprint
final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
if (fpm != null && fpm.isHardwareDetected()) {
// This catches the title which can be overloaded in an overlay
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.security_settings_fingerprint_preference_title);
data.key = "security_fingerprint";
data.screenTitle = screenTitle;
result.add(data);
// Fallback for when the above doesn't contain "fingerprint"
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.fingerprint_manage_category_title);
data.key = "security_managed_fingerprint";
data.screenTitle = screenTitle;
result.add(data);
}
final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
if (profileUserId != UserHandle.USER_NULL
&& lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
if (lockPatternUtils.getKeyguardStoredPasswordQuality(profileUserId)
>= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& lockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
profileUserId)) {
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.lock_settings_profile_unification_title);
data.key = "security_use_one_lock";
data.screenTitle = screenTitle;
result.add(data);
}
}
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
// Do not display SIM lock for devices without an Icc card
final UserManager um = UserManager.get(context);
final TelephonyManager tm = TelephonyManager.from(context);
if (!um.isAdminUser() || !tm.hasIccCard()) {
keys.add(KEY_SIM_LOCK);
}
// TrustAgent settings disappear when the user has no primary security.
if (!lockPatternUtils.isSecure(MY_USER_ID)) {
keys.add(KEY_TRUST_AGENT);
keys.add(KEY_MANAGE_TRUST_AGENTS);
}
if (!(new EnterprisePrivacyPreferenceController(context))
.isAvailable()) {
keys.add(KEY_ENTERPRISE_PRIVACY);
}
// Duplicate in special app access
keys.add(KEY_MANAGE_DEVICE_ADMIN);
// Duplicates between parent-child
keys.add(KEY_LOCATION);
keys.add(KEY_ENCRYPTION_AND_CREDENTIALS);
keys.add(KEY_SCREEN_PINNING);
keys.add(KEY_LOCATION_SCANNING);
return keys;
}
}
static class SummaryProvider implements SummaryLoader.SummaryProvider {
private final Context mContext;
private final SummaryLoader mSummaryLoader;
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
mContext = context;
mSummaryLoader = summaryLoader;
}
@Override
public void setListening(boolean listening) {
if (listening) {
final FingerprintManager fpm =
Utils.getFingerprintManagerOrNull(mContext);
if (fpm != null && fpm.isHardwareDetected()) {
mSummaryLoader.setSummary(this,
mContext.getString(R.string.security_dashboard_summary));
} else {
mSummaryLoader.setSummary(this, mContext.getString(
R.string.security_dashboard_summary_no_fingerprint));
}
}
}
}
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
new SummaryLoader.SummaryProviderFactory() {
@Override
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
SummaryLoader summaryLoader) {
return new SummaryProvider(activity, summaryLoader);
}
};
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.os.Bundle;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
public class UnificationConfirmationDialog extends InstrumentedDialogFragment {
private static final String EXTRA_COMPLIANT = "compliant";
public static UnificationConfirmationDialog newIntance(boolean compliant) {
UnificationConfirmationDialog
dialog = new UnificationConfirmationDialog();
Bundle args = new Bundle();
args.putBoolean(EXTRA_COMPLIANT, compliant);
dialog.setArguments(args);
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 SecuritySettingsV2 parentFragment = ((SecuritySettingsV2) getParentFragment());
final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.lock_settings_profile_unification_dialog_title)
.setMessage(compliant ? R.string.lock_settings_profile_unification_dialog_body
: R.string.lock_settings_profile_unification_dialog_uncompliant_body)
.setPositiveButton(
compliant ? R.string.lock_settings_profile_unification_dialog_confirm
: R.string.lock_settings_profile_unification_dialog_uncompliant_confirm,
(dialog, whichButton) -> {
if (compliant) {
parentFragment.launchConfirmDeviceLockForUnification();
} else {
parentFragment.unifyUncompliantLocks();
}
}
)
.setNegativeButton(R.string.cancel, null)
.create();
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
((SecuritySettingsV2) getParentFragment()).updateUnificationPreference();
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.DIALOG_UNIFICATION_CONFIRMATION;
}
}

View File

@@ -1,2 +1,3 @@
com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
com.android.settings.search.indexing.FakeSettingsFragment com.android.settings.search.indexing.FakeSettingsFragment
com.android.settings.security.SecuritySettingsV2

View File

@@ -16,6 +16,7 @@ import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableResources; import com.android.settings.search.SearchIndexableResources;
import com.android.settings.search.XmlParserUtils; import com.android.settings.search.XmlParserUtils;
import com.android.settings.security.SecuritySettings; import com.android.settings.security.SecuritySettings;
import com.android.settings.security.SecuritySettingsV2;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After; import org.junit.After;
@@ -42,7 +43,8 @@ public class XmlControllerAttributeTest {
// List of classes that are too hard to mock in order to retrieve xml information. // List of classes that are too hard to mock in order to retrieve xml information.
private final List<Class> illegalClasses = new ArrayList<>( private final List<Class> illegalClasses = new ArrayList<>(
Arrays.asList( Arrays.asList(
SecuritySettings.class SecuritySettings.class,
SecuritySettingsV2.class
)); ));
// List of XML that could be retrieved from the illegalClasses list. // List of XML that could be retrieved from the illegalClasses list.