Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)

Bug: 166295507
Merged-In: Ie9d2c4d6d4618a167af1c5627d5d7918a404f398
Change-Id: I2ae428e37fd96226ce4e06032e2c0beaacbd0301
This commit is contained in:
Xin Li
2020-08-28 13:20:55 -07:00
2628 changed files with 514897 additions and 439664 deletions

View File

@@ -31,6 +31,7 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.security.screenlock.ScreenLockSettings;
@@ -39,6 +40,7 @@ import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class ChangeScreenLockPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, GearPreference.OnGearClickListener {
@@ -52,6 +54,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
protected final int mUserId = UserHandle.myUserId();
protected final int mProfileChallengeUserId;
private final MetricsFeatureProvider mMetricsFeatureProvider;
protected RestrictedPreference mPreference;
@@ -64,6 +67,7 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
.getLockPatternUtils(context);
mHost = host;
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@Override
@@ -104,6 +108,8 @@ public class ChangeScreenLockPreferenceController extends AbstractPreferenceCont
@Override
public void onGearClick(GearPreference p) {
if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
mMetricsFeatureProvider.logClickedPreference(p,
p.getExtras().getInt(DashboardFragment.CATEGORY));
new SubSettingLauncher(mContext)
.setDestination(ScreenLockSettings.class.getName())
.setSourceMetricsCategory(mHost.getMetricsCategory())

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2020 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.KeyguardManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/** Enable/disable user confirmation before deleting an eSim */
public class ConfirmSimDeletionPreferenceController extends BasePreferenceController implements
Preference.OnPreferenceChangeListener{
public static final String KEY_CONFIRM_SIM_DELETION = "confirm_sim_deletion";
private boolean mConfirmationDefaultOn;
private MetricsFeatureProvider mMetricsFeatureProvider;
public ConfirmSimDeletionPreferenceController(Context context, String key) {
super(context, key);
mConfirmationDefaultOn =
context.getResources()
.getBoolean(R.bool.config_sim_deletion_confirmation_default_on);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@Override
public int getAvailabilityStatus() {
// hide if eSim is not supported on the device
return MobileNetworkUtils.showEuiccSettings(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
private boolean getGlobalState() {
return Settings.Global.getInt(
mContext.getContentResolver(),
KEY_CONFIRM_SIM_DELETION,
mConfirmationDefaultOn ? 1 : 0)
== 1;
}
public boolean isChecked() {
return getGlobalState();
}
public boolean setChecked(boolean isChecked) {
Settings.Global.putInt(
mContext.getContentResolver(), KEY_CONFIRM_SIM_DELETION, isChecked ? 1 : 0);
return true;
}
// handle UI change
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (!preference.getKey().equals(getPreferenceKey())) {
return false;
}
if (!isChecked()) {
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_CONFIRM_SIM_DELETION_ON);
setChecked(true);
return true;
} else {
// prevent disabling the feature until authorized
WifiDppUtils.showLockScreen(mContext, () -> {
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_CONFIRM_SIM_DELETION_OFF);
// set data
setChecked(false);
// set UI
((TwoStatePreference) preference).setChecked(false);
});
return false;
}
}
@Override
public void updateState(Preference preference) {
final KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class);
if (!keyguardManager.isKeyguardSecure()) {
preference.setEnabled(false);
if (preference instanceof TwoStatePreference) {
((TwoStatePreference) preference).setChecked(false);
}
preference.setSummary(R.string.disabled_because_no_backup_security);
} else {
preference.setEnabled(true);
if (preference instanceof TwoStatePreference) {
((TwoStatePreference) preference).setChecked(getGlobalState());
}
preference.setSummary(R.string.confirm_sim_deletion_description);
}
}
}

View File

@@ -37,6 +37,7 @@ import android.widget.Button;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.CryptKeeperConfirm;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -193,9 +194,10 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
// confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK && data != null) {
int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1);
byte[] password = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (!(password == null || password.length == 0)) {
showFinalConfirmation(type, password);
LockscreenCredential password = data.getParcelableExtra(
ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (password != null && !password.isNone()) {
showFinalConfirmation(type, password.getCredential());
}
}
}

View File

@@ -21,7 +21,6 @@ import static com.android.settings.security.EncryptionStatusPreferenceController
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -87,28 +86,19 @@ public class EncryptionAndCredential extends DashboardFragment {
/**
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new SecuritySearchIndexProvider();
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.encryption_and_credential) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null /* lifecycle */);
}
private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.encryption_and_credential;
return Arrays.asList(sir);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, null /* lifecycle */);
}
@Override
protected boolean isPageSearchEnabled(Context context) {
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
return um.isAdminUser();
}
}
@Override
protected boolean isPageSearchEnabled(Context context) {
final UserManager um = (UserManager) context.getSystemService(
Context.USER_SERVICE);
return um.isAdminUser();
}
};
}

View File

@@ -17,7 +17,6 @@
package com.android.settings.security;
import android.content.Context;
import android.os.UserManager;
import com.android.settings.core.BasePreferenceController;
@@ -27,16 +26,11 @@ public class InstallCaCertificatePreferenceController extends
private static final String KEY_INSTALL_CA_CERTIFICATE = "install_ca_certificate";
public InstallCaCertificatePreferenceController(Context context) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
super(context, KEY_INSTALL_CA_CERTIFICATE);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public String getPreferenceKey() {
return KEY_INSTALL_CA_CERTIFICATE;
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2019 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.annotation.Nullable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.security.Credentials;
import android.view.View;
import android.widget.Toast;
import com.android.settings.R;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.GlifLayout;
/**
* Creates a warning dialog explaining the consequences of installing a CA certificate
* This is displayed before a CA certificate can be installed from Settings.
*/
public class InstallCaCertificateWarning extends Activity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ca_certificate_warning_dialog);
final GlifLayout layout = findViewById(R.id.setup_wizard_layout);
final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
mixin.setSecondaryButton(
new FooterButton.Builder(this)
.setText(R.string.certificate_warning_install_anyway)
.setListener(installCaCertificate())
.setButtonType(FooterButton.ButtonType.OTHER)
.setTheme(R.style.SudGlifButton_Secondary)
.build()
);
mixin.setPrimaryButton(
new FooterButton.Builder(this)
.setText(R.string.certificate_warning_dont_install)
.setListener(returnToInstallCertificateFromStorage())
.setButtonType(FooterButton.ButtonType.NEXT)
.setTheme(R.style.SudGlifButton_Primary)
.build()
);
}
private View.OnClickListener installCaCertificate() {
return v -> {
final Intent intent = new Intent();
intent.setAction(Credentials.INSTALL_ACTION);
intent.putExtra(Credentials.EXTRA_CERTIFICATE_USAGE, Credentials.CERTIFICATE_USAGE_CA);
startActivity(intent);
finish();
};
}
private View.OnClickListener returnToInstallCertificateFromStorage() {
return v -> {
Toast.makeText(this, R.string.cert_not_installed, Toast.LENGTH_SHORT).show();
finish();
};
}
}

View File

@@ -55,7 +55,7 @@ public class InstallCertificateFromStorage extends DashboardFragment {
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return new ArrayList<AbstractPreferenceController>();
return buildPreferenceControllers(context, getSettingsLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
@@ -76,7 +76,7 @@ public class InstallCertificateFromStorage extends DashboardFragment {
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
new BaseSearchIndexProvider(R.xml.install_certificate_from_storage) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {

View File

@@ -17,7 +17,6 @@
package com.android.settings.security;
import android.content.Context;
import android.os.UserManager;
import com.android.settings.core.BasePreferenceController;
@@ -27,16 +26,11 @@ public class InstallUserCertificatePreferenceController extends
private static final String KEY_INSTALL_USER_CERTIFICATE = "install_user_certificate";
public InstallUserCertificatePreferenceController(Context context) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
super(context, KEY_INSTALL_USER_CERTIFICATE);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public String getPreferenceKey() {
return KEY_INSTALL_USER_CERTIFICATE;
}
}

View File

@@ -17,7 +17,6 @@
package com.android.settings.security;
import android.content.Context;
import android.os.UserManager;
import com.android.settings.core.BasePreferenceController;
@@ -27,16 +26,11 @@ public class InstallWifiCertificatePreferenceController extends
private static final String KEY_INSTALL_WIFI_CERTIFICATE = "install_wifi_certificate";
public InstallWifiCertificatePreferenceController(Context context) {
super(context, UserManager.DISALLOW_CONFIG_CREDENTIALS);
super(context, KEY_INSTALL_WIFI_CERTIFICATE);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public String getPreferenceKey() {
return KEY_INSTALL_WIFI_CERTIFICATE;
}
}

View File

@@ -16,7 +16,6 @@
package com.android.settings.security;
import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
import static com.android.settings.security.SecuritySettings.UNIFY_LOCK_CONFIRM_PROFILE_REQUEST;
import static com.android.settings.security.SecuritySettings.UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST;
@@ -32,6 +31,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
@@ -47,12 +47,14 @@ import com.android.settingslib.core.AbstractPreferenceController;
* Controller for password unification/un-unification flows.
*
* When password is being unified, there may be two cases:
* 1. If work password is not empty and satisfies device-wide policies (if any), it will be made
* into device-wide password. To do that we need both current device and profile passwords
* because both of them will be changed as a result.
* 2. Otherwise device-wide password is preserved. In this case we only need current profile
* password, but after unifying the passwords we proceed to ask the user for a new device
* password.
* 1. If device password will satisfy device-wide policies post-unification (when password policy
* set on the work challenge will be enforced on device password), the device password is
* preserved while work challenge is unified. Only the current work challenge is required
* in this flow.
* 2. Otherwise the user will need to enroll a new compliant device password before unification
* takes place. In this case we first confirm the current work challenge, then guide the user
* through an enrollment flow for the new device password, and finally unify the work challenge
* at the very end.
*/
public class LockUnificationPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -70,9 +72,9 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
private RestrictedSwitchPreference mUnifyProfile;
private byte[] mCurrentDevicePassword;
private byte[] mCurrentProfilePassword;
private boolean mKeepDeviceLock;
private LockscreenCredential mCurrentDevicePassword;
private LockscreenCredential mCurrentProfilePassword;
private boolean mRequireNewDevicePassword;
@Override
public void displayPreference(PreferenceScreen screen) {
@@ -89,6 +91,8 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mProfileUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
mCurrentDevicePassword = LockscreenCredential.createNone();
mCurrentProfilePassword = LockscreenCredential.createNone();
}
@Override
@@ -109,13 +113,9 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
}
final boolean useOneLock = (Boolean) value;
if (useOneLock) {
// Keep current device (personal) lock if the profile lock is empty or is not compliant
// with the policy on personal side.
mKeepDeviceLock =
mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileUserId)
< DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|| !mDpm.isProfileActivePasswordSufficientForParent(mProfileUserId);
UnificationConfirmationDialog.newInstance(!mKeepDeviceLock).show(mHost);
mRequireNewDevicePassword = !mDpm.isPasswordSufficientAfterProfileUnification(
UserHandle.myUserId(), mProfileUserId);
startUnification();
} else {
final String title = mContext.getString(R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
@@ -146,18 +146,14 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
ununifyLocks();
return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentDevicePassword =
data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
launchConfirmProfileLock();
data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
ununifyLocks();
return true;
} else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
&& resultCode == Activity.RESULT_OK) {
mCurrentProfilePassword =
data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
data.getParcelableExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
unifyLocks();
return true;
}
@@ -167,76 +163,44 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
private void ununifyLocks() {
final Bundle extras = new Bundle();
extras.putInt(Intent.EXTRA_USER_ID, mProfileUserId);
extras.putParcelable(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, mCurrentDevicePassword);
new SubSettingLauncher(mContext)
.setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
.setTitleRes(R.string.lock_settings_picker_title_profile)
.setTitleRes(R.string.lock_settings_picker_title_profile)
.setSourceMetricsCategory(mHost.getMetricsCategory())
.setArguments(extras)
.launch();
}
/** Asks the user to confirm device lock (if there is one) and proceeds to ask profile lock. */
private void launchConfirmDeviceAndProfileLock() {
final String title = mContext.getString(
R.string.unlock_set_unlock_launch_picker_title);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
launchConfirmProfileLock();
}
}
private void launchConfirmProfileLock() {
void startUnification() {
// Confirm profile lock
final String title = mContext.getString(
R.string.unlock_set_unlock_launch_picker_title_profile);
final ChooseLockSettingsHelper helper =
new ChooseLockSettingsHelper(mHost.getActivity(), mHost);
if (!helper.launchConfirmationActivity(
UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileUserId)) {
// If profile has no lock, go straight to unification.
unifyLocks();
// TODO: update relevant prefs.
// createPreferenceHierarchy();
}
}
void startUnification() {
// If the device lock stays the same, only confirm profile lock. Otherwise confirm both.
if (mKeepDeviceLock) {
launchConfirmProfileLock();
} else {
launchConfirmDeviceAndProfileLock();
}
}
private void unifyLocks() {
if (mKeepDeviceLock) {
if (mRequireNewDevicePassword) {
promptForNewDeviceLockAndThenUnify();
} else {
unifyKeepingDeviceLock();
promptForNewDeviceLock();
} else {
unifyKeepingWorkLock();
}
mCurrentDevicePassword = null;
mCurrentProfilePassword = null;
}
private void unifyKeepingWorkLock() {
final int profileQuality =
mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileUserId);
// PASSWORD_QUALITY_SOMETHING means pattern, everything above means PIN/password.
if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
mLockPatternUtils.saveLockPattern(
LockPatternUtils.byteArrayToPattern(mCurrentProfilePassword),
mCurrentDevicePassword, MY_USER_ID);
} else {
mLockPatternUtils.saveLockPassword(
mCurrentProfilePassword, mCurrentDevicePassword, profileQuality, MY_USER_ID);
if (mCurrentDevicePassword != null) {
mCurrentDevicePassword.zeroize();
mCurrentDevicePassword = null;
}
if (mCurrentProfilePassword != null) {
mCurrentProfilePassword.zeroize();
mCurrentProfilePassword = null;
}
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileUserId, false,
mCurrentProfilePassword);
final boolean profilePatternVisibility =
mLockPatternUtils.isVisiblePatternEnabled(mProfileUserId);
mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
}
private void unifyKeepingDeviceLock() {
@@ -244,11 +208,16 @@ public class LockUnificationPreferenceController extends AbstractPreferenceContr
mCurrentProfilePassword);
}
private void promptForNewDeviceLock() {
private void promptForNewDeviceLockAndThenUnify() {
final Bundle extras = new Bundle();
extras.putInt(ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID, mProfileUserId);
extras.putParcelable(ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_CREDENTIAL,
mCurrentProfilePassword);
new SubSettingLauncher(mContext)
.setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
.setTitleRes(R.string.lock_settings_picker_title)
.setSourceMetricsCategory(mHost.getMetricsCategory())
.setArguments(extras)
.launch();
}

View File

@@ -19,7 +19,6 @@ package com.android.settings.security;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.hardware.display.AmbientDisplayConfiguration;
import android.provider.SearchIndexableResource;
import androidx.annotation.VisibleForTesting;
@@ -37,7 +36,6 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -109,8 +107,7 @@ public class LockscreenDashboardFragment extends DashboardFragment
KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE);
lifecycle.addObserver(notificationController);
controllers.add(notificationController);
mOwnerInfoPreferenceController =
new OwnerInfoPreferenceController(context, this, lifecycle);
mOwnerInfoPreferenceController = new OwnerInfoPreferenceController(context, this);
controllers.add(mOwnerInfoPreferenceController);
return controllers;
@@ -130,15 +127,8 @@ public class LockscreenDashboardFragment extends DashboardFragment
return mConfig;
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.security_lockscreen_settings;
return Arrays.asList(sir);
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.security_lockscreen_settings) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
@@ -146,7 +136,7 @@ public class LockscreenDashboardFragment extends DashboardFragment
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new LockScreenNotificationPreferenceController(context));
controllers.add(new OwnerInfoPreferenceController(
context, null /* fragment */, null /* lifecycle */));
context, null /* fragment */));
return controllers;
}

View File

@@ -17,11 +17,10 @@ package com.android.settings.security;
import android.content.Context;
import android.os.UserHandle;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
@@ -31,18 +30,19 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
import com.android.settingslib.core.lifecycle.events.OnResume;
public class OwnerInfoPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnResume {
private static final String KEY_OWNER_INFO = "owner_info_settings";
@VisibleForTesting
static final String KEY_OWNER_INFO = "owner_info_settings";
private static final int MY_USER_ID = UserHandle.myUserId();
private final LockPatternUtils mLockPatternUtils;
private final Fragment mParent;
private final ObservablePreferenceFragment mParent;
private RestrictedPreference mOwnerInfoPref;
// Container fragment should implement this in order to show the correct summary
@@ -50,12 +50,12 @@ public class OwnerInfoPreferenceController extends AbstractPreferenceController
void onOwnerInfoUpdated();
}
public OwnerInfoPreferenceController(Context context, Fragment parent, Lifecycle lifecycle ) {
public OwnerInfoPreferenceController(Context context, ObservablePreferenceFragment parent) {
super(context);
mParent = parent;
mLockPatternUtils = new LockPatternUtils(context);
if (lifecycle != null) {
lifecycle.addObserver(this);
if (parent != null) {
parent.getSettingsLifecycle().addObserver(this);
}
}
@@ -80,6 +80,15 @@ public class OwnerInfoPreferenceController extends AbstractPreferenceController
return KEY_OWNER_INFO;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (TextUtils.equals(getPreferenceKey(), preference.getKey())) {
OwnerInfoSettings.show(mParent);
return true;
}
return false;
}
public void updateEnableState() {
if (mOwnerInfoPref == null) {
return;
@@ -90,16 +99,6 @@ public class OwnerInfoPreferenceController extends AbstractPreferenceController
} else {
mOwnerInfoPref.setDisabledByAdmin(null);
mOwnerInfoPref.setEnabled(!mLockPatternUtils.isLockScreenDisabled(MY_USER_ID));
if (mOwnerInfoPref.isEnabled()) {
mOwnerInfoPref.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
OwnerInfoSettings.show(mParent);
return true;
}
});
}
}
}

View File

@@ -18,16 +18,16 @@ package com.android.settings.security;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Switch;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceScreen;
@@ -41,23 +41,28 @@ import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.FooterPreference;
import java.util.Arrays;
import java.util.List;
/**
* Screen pinning settings.
*/
@SearchIndexable
public class ScreenPinningSettings extends SettingsPreferenceFragment
implements SwitchBar.OnSwitchChangeListener {
implements SwitchBar.OnSwitchChangeListener, DialogInterface.OnClickListener {
private static final CharSequence KEY_USE_SCREEN_LOCK = "use_screen_lock";
private static final String KEY_USE_SCREEN_LOCK = "use_screen_lock";
private static final String KEY_FOOTER = "screen_pinning_settings_screen_footer";
private static final int CHANGE_LOCK_METHOD_REQUEST = 43;
private SwitchBar mSwitchBar;
private SwitchPreference mUseScreenLock;
private FooterPreference mFooterPreference;
private LockPatternUtils mLockPatternUtils;
private UserManager mUserManager;
@Override
public int getMetricsCategory() {
@@ -71,12 +76,19 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
final SettingsActivity activity = (SettingsActivity) getActivity();
activity.setTitle(R.string.screen_pinning_title);
mLockPatternUtils = new LockPatternUtils(activity);
mUserManager = activity.getSystemService(UserManager.class);
addPreferencesFromResource(R.xml.screen_pinning_settings);
final PreferenceScreen root = getPreferenceScreen();
mUseScreenLock = root.findPreference(KEY_USE_SCREEN_LOCK);
mFooterPreference = root.findPreference(KEY_FOOTER);
mSwitchBar = activity.getSwitchBar();
mSwitchBar.addOnSwitchChangeListener(this);
mSwitchBar.show();
mSwitchBar.setChecked(isLockToAppEnabled(getActivity()));
mSwitchBar.addOnSwitchChangeListener(this);
updateDisplay();
}
@Override
@@ -84,16 +96,6 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
return R.string.help_url_screen_pinning;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewGroup parent = (ViewGroup) view.findViewById(android.R.id.list_container);
View emptyView = LayoutInflater.from(getContext())
.inflate(R.layout.screen_pinning_instructions, parent, false);
parent.addView(emptyView);
setEmptyView(emptyView);
}
@Override
public void onDestroyView() {
super.onDestroyView();
@@ -188,20 +190,32 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
*/
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
setLockToAppEnabled(isChecked);
if (isChecked) {
new AlertDialog.Builder(getContext())
.setMessage(R.string.screen_pinning_dialog_message)
.setPositiveButton(R.string.dlg_ok, this)
.setNegativeButton(R.string.dlg_cancel, this)
.setCancelable(false)
.show();
} else {
setLockToAppEnabled(false);
updateDisplay();
}
}
@Override
public void onClick(DialogInterface dialogInterface, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
setLockToAppEnabled(true);
} else {
mSwitchBar.setChecked(false);
}
updateDisplay();
}
public void updateDisplay() {
PreferenceScreen root = getPreferenceScreen();
if (root != null) {
root.removeAll();
}
private void updateDisplay() {
if (isLockToAppEnabled(getActivity())) {
addPreferencesFromResource(R.xml.screen_pinning_settings);
root = getPreferenceScreen();
mUseScreenLock = (SwitchPreference) root.findPreference(KEY_USE_SCREEN_LOCK);
mUseScreenLock.setVisible(true);
mUseScreenLock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -210,21 +224,35 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
});
mUseScreenLock.setChecked(isScreenLockUsed());
mUseScreenLock.setTitle(getCurrentSecurityTitle());
} else {
mFooterPreference.setSummary(getAppPinningContent());
mUseScreenLock.setVisible(false);
}
}
private boolean isGuestModeSupported() {
return UserManager.supportsMultipleUsers()
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
}
private CharSequence getAppPinningContent() {
return isGuestModeSupported()
? getActivity().getText(R.string.screen_pinning_guest_user_description)
: getActivity().getText(R.string.screen_pinning_description);
}
/**
* For search
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.screen_pinning_settings;
return Arrays.asList(sir);
}
};
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.screen_pinning_settings;
return Arrays.asList(sir);
}
};
}

View File

@@ -20,7 +20,6 @@ import static com.android.settings.security.EncryptionStatusPreferenceController
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController;
@@ -48,7 +47,6 @@ public class SecuritySettings extends DashboardFragment {
private static final String WORK_PROFILE_SECURITY_CATEGORY = "security_category_profile";
public static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
public static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
public static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
public static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
@@ -138,19 +136,8 @@ public class SecuritySettings extends DashboardFragment {
/**
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final List<SearchIndexableResource> index = new ArrayList<>();
// Append the rest of the settings
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.security_dashboard_settings;
index.add(sir);
return index;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.security_dashboard_settings) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(Context

View File

@@ -32,7 +32,7 @@ public class TopLevelSecurityEntryPreferenceController extends BasePreferenceCon
@Override
public int getAvailabilityStatus() {
return AVAILABLE_UNSEARCHABLE;
return AVAILABLE;
}
@Override

View File

@@ -16,8 +16,6 @@
package com.android.settings.security.screenlock;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import android.content.Context;
import android.os.UserHandle;
@@ -52,14 +50,7 @@ public class LockScreenPreferenceController extends BasePreferenceController imp
@Override
public int getAvailabilityStatus() {
if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
return mLockPatternUtils.isLockScreenDisabled(MY_USER_ID)
? DISABLED_FOR_USER : AVAILABLE_UNSEARCHABLE;
} else {
return mLockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)
== PASSWORD_QUALITY_UNSPECIFIED
? DISABLED_FOR_USER : AVAILABLE_UNSEARCHABLE;
}
return AVAILABLE;
}
@Override

View File

@@ -19,18 +19,13 @@ package com.android.settings.security.screenlock;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.UserHandle;
import android.provider.SearchIndexableResource;
import androidx.fragment.app.Fragment;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.security.OwnerInfoPreferenceController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
@@ -63,8 +58,7 @@ public class ScreenLockSettings extends DashboardFragment
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mLockPatternUtils = new LockPatternUtils(context);
return buildPreferenceControllers(context, this /* parent */, getSettingsLifecycle(),
mLockPatternUtils);
return buildPreferenceControllers(context, this /* parent */, mLockPatternUtils);
}
@Override
@@ -73,7 +67,7 @@ public class ScreenLockSettings extends DashboardFragment
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Fragment parent, Lifecycle lifecycle, LockPatternUtils lockPatternUtils) {
DashboardFragment parent, LockPatternUtils lockPatternUtils) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new PatternVisiblePreferenceController(
context, MY_USER_ID, lockPatternUtils));
@@ -81,29 +75,18 @@ public class ScreenLockSettings extends DashboardFragment
context, MY_USER_ID, lockPatternUtils));
controllers.add(new LockAfterTimeoutPreferenceController(
context, MY_USER_ID, lockPatternUtils));
controllers.add(new OwnerInfoPreferenceController(context, parent, lifecycle));
controllers.add(new OwnerInfoPreferenceController(context, parent));
return controllers;
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
final ArrayList<SearchIndexableResource> result = new ArrayList<>();
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.screen_lock_settings;
result.add(sir);
return result;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.screen_lock_settings) {
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null /* parent */,
null /* lifecycle */, new LockPatternUtils(context));
new LockPatternUtils(context));
}
};
}

View File

@@ -23,7 +23,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -44,7 +43,9 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.search.SearchIndexableRaw;
import java.util.ArrayList;
import java.util.List;
public class TrustAgentListPreferenceController extends AbstractPreferenceController
@@ -65,6 +66,9 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
private Intent mTrustAgentClickIntent;
private PreferenceCategory mSecurityCategory;
@VisibleForTesting
final List<String> mTrustAgentsKeyList;
public TrustAgentListPreferenceController(Context context, SecuritySettings host,
Lifecycle lifecycle) {
super(context);
@@ -73,6 +77,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
mHost = host;
mLockPatternUtils = provider.getLockPatternUtils(context);
mTrustAgentManager = provider.getTrustAgentManager();
mTrustAgentsKeyList = new ArrayList();
if (lifecycle != null) {
lifecycle.addObserver(this);
}
@@ -112,7 +117,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
if (!mTrustAgentsKeyList.contains(preference.getKey())) {
return super.handlePreferenceTreeClick(preference);
}
final ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(
@@ -134,34 +139,70 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro
updateTrustAgents();
}
@Override
public void updateDynamicRawDataToIndex(List<SearchIndexableRaw> rawData) {
if (!isAvailable()) {
return;
}
final List<TrustAgentManager.TrustAgentComponentInfo> agents = getActiveTrustAgents(
mContext);
if (agents == null) {
return;
}
for (int i = 0, size = agents.size(); i < size; i++) {
final SearchIndexableRaw raw = new SearchIndexableRaw(mContext);
final TrustAgentManager.TrustAgentComponentInfo agent = agents.get(i);
raw.key = PREF_KEY_TRUST_AGENT + i;
raw.title = agent.title;
rawData.add(raw);
}
}
/**
* @return The active trust agents from TrustAgentManager.
*/
private List<TrustAgentManager.TrustAgentComponentInfo> getActiveTrustAgents(Context context) {
return mTrustAgentManager.getActiveTrustAgents(context, mLockPatternUtils);
}
private void updateTrustAgents() {
if (mSecurityCategory == null) {
return;
}
// If for some reason the preference is no longer available, don't proceed to add.
if (!isAvailable()) {
return;
}
final List<TrustAgentManager.TrustAgentComponentInfo> agents = getActiveTrustAgents(
mContext);
if (agents == null) {
return;
}
// First remove all old trust agents.
while (true) {
final Preference oldAgent = mSecurityCategory.findPreference(PREF_KEY_TRUST_AGENT);
for (int i = 0, size = agents.size(); i < size; i++) {
String key = PREF_KEY_TRUST_AGENT + i;
final Preference oldAgent = mSecurityCategory.findPreference(key);
if (oldAgent == null) {
break;
} else {
mSecurityCategory.removePreference(oldAgent);
}
}
// If for some reason the preference is no longer available, don't proceed to add.
if (!isAvailable()) {
return;
}
mTrustAgentsKeyList.clear();
// Then add new ones.
final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
final List<TrustAgentManager.TrustAgentComponentInfo> agents =
mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils);
if (agents == null) {
return;
}
for (TrustAgentManager.TrustAgentComponentInfo agent : agents) {
for (int i = 0, size = agents.size(); i < size; i++) {
final RestrictedPreference trustAgentPreference =
new RestrictedPreference(mSecurityCategory.getContext());
trustAgentPreference.setKey(PREF_KEY_TRUST_AGENT);
TrustAgentManager.TrustAgentComponentInfo agent = agents.get(i);
mTrustAgentsKeyList.add(PREF_KEY_TRUST_AGENT + i);
trustAgentPreference.setKey(PREF_KEY_TRUST_AGENT + i);
trustAgentPreference.setTitle(agent.title);
trustAgentPreference.setSummary(agent.summary);
// Create intent for this preference.

View File

@@ -23,7 +23,7 @@ import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
@@ -53,16 +53,6 @@ public class TrustAgentSettings extends DashboardFragment {
return R.xml.trust_agent_settings;
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final List<SearchIndexableResource> result = new ArrayList<>();
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.trust_agent_settings;
result.add(sir);
return result;
}
};
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.trust_agent_settings);
}