Merge "Route to active unlock component"
diff --git a/src/com/android/settings/biometrics/activeunlock/ActiveUnlockRequireBiometricSetup.java b/src/com/android/settings/biometrics/activeunlock/ActiveUnlockRequireBiometricSetup.java
index 60cc16e..1f30e56 100644
--- a/src/com/android/settings/biometrics/activeunlock/ActiveUnlockRequireBiometricSetup.java
+++ b/src/com/android/settings/biometrics/activeunlock/ActiveUnlockRequireBiometricSetup.java
@@ -49,14 +49,17 @@
@VisibleForTesting
static final int BIOMETRIC_ENROLL_REQUEST = 1001;
+ private static final int ACTIVE_UNLOCK_REQUEST = 1002;
private long mGkPwHandle;
private boolean mNextClicked;
+ private ActiveUnlockStatusUtils mActiveUnlockStatusUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activeunlock_require_biometric_setup);
+ mActiveUnlockStatusUtils = new ActiveUnlockStatusUtils(this);
mUserId = getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
Log.i(TAG, "mUserId = " + mUserId);
mGkPwHandle = getIntent().getLongExtra(EXTRA_KEY_GK_PW_HANDLE, 0L);
@@ -132,8 +135,10 @@
CombinedBiometricStatusUtils combinedBiometricStatusUtils =
new CombinedBiometricStatusUtils(this, mUserId);
if (combinedBiometricStatusUtils.hasEnrolled()) {
- // TODO(b/264813444): launch active unlock setting page in GmsCore without double
- // authentication.
+ Intent activeUnlockIntent = mActiveUnlockStatusUtils.getIntent();
+ if (activeUnlockIntent != null) {
+ startActivityForResult(activeUnlockIntent, ACTIVE_UNLOCK_REQUEST);
+ }
}
}
mNextClicked = false;
diff --git a/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceController.java b/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceController.java
index 05d4acb..31c72ae 100644
--- a/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceController.java
+++ b/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceController.java
@@ -28,6 +28,7 @@
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricStatusPreferenceController;
import com.android.settings.biometrics.activeunlock.ActiveUnlockContentListener.OnContentChangedListener;
+import com.android.settings.biometrics.combination.CombinedBiometricStatusUtils;
import com.android.settingslib.RestrictedPreference;
/**
@@ -35,8 +36,7 @@
* controls the ability to unlock the phone with watch authentication.
*/
public class ActiveUnlockStatusPreferenceController
- extends BiometricStatusPreferenceController
- implements LifecycleObserver, OnContentChangedListener {
+ extends BiometricStatusPreferenceController implements LifecycleObserver {
/**
* Preference key.
*
@@ -47,7 +47,9 @@
@Nullable private PreferenceScreen mPreferenceScreen;
@Nullable private String mSummary;
private final ActiveUnlockStatusUtils mActiveUnlockStatusUtils;
+ private final CombinedBiometricStatusUtils mCombinedBiometricStatusUtils;
private final ActiveUnlockSummaryListener mActiveUnlockSummaryListener;
+ private final ActiveUnlockDeviceNameListener mActiveUnlockDeviceNameListener;
public ActiveUnlockStatusPreferenceController(@NonNull Context context) {
this(context, KEY_ACTIVE_UNLOCK_SETTINGS);
@@ -57,7 +59,31 @@
@NonNull Context context, @NonNull String key) {
super(context, key);
mActiveUnlockStatusUtils = new ActiveUnlockStatusUtils(context);
- mActiveUnlockSummaryListener = new ActiveUnlockSummaryListener(context, this);
+ mCombinedBiometricStatusUtils = new CombinedBiometricStatusUtils(context, getUserId());
+ OnContentChangedListener onSummaryChangedListener = new OnContentChangedListener() {
+ @Override
+ public void onContentChanged(String newContent) {
+ mSummary = newContent;
+ if (mPreference != null) {
+ mPreference.setSummary(getSummaryText());
+ }
+ }
+ };
+ OnContentChangedListener onDeviceNameChangedListener =
+ new OnContentChangedListener() {
+
+ @Override
+ public void onContentChanged(String newContent) {
+ if (mPreference != null) {
+ mPreference.setSummary(getSummaryText());
+ }
+ }
+
+ };
+ mActiveUnlockSummaryListener =
+ new ActiveUnlockSummaryListener(context, onSummaryChangedListener);
+ mActiveUnlockDeviceNameListener =
+ new ActiveUnlockDeviceNameListener(context, onDeviceNameChangedListener);
}
@@ -65,6 +91,7 @@
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
mActiveUnlockSummaryListener.subscribe();
+ mActiveUnlockDeviceNameListener.subscribe();
}
/** Resets the preference reference on resume. */
@@ -79,14 +106,7 @@
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
mActiveUnlockSummaryListener.unsubscribe();
- }
-
- @Override
- public void onContentChanged(String newContent) {
- mSummary = newContent;
- if (mPreference != null) {
- mPreference.setSummary(getSummaryText());
- }
+ mActiveUnlockDeviceNameListener.unsubscribe();
}
@Override
@@ -120,6 +140,15 @@
@Override
protected String getSummaryText() {
+ if (mActiveUnlockStatusUtils.useBiometricFailureLayout()
+ && !mActiveUnlockDeviceNameListener.hasEnrolled()
+ && !mCombinedBiometricStatusUtils.hasEnrolled()) {
+ @Nullable final String setupString =
+ mActiveUnlockStatusUtils.getSummaryWhenBiometricSetupRequired();
+ if (setupString != null) {
+ return setupString;
+ }
+ }
if (mSummary == null) {
// return non-empty string to prevent re-sizing of the tile
return " ";
@@ -129,7 +158,6 @@
@Override
protected String getSettingsClassName() {
- // TODO(b/264813445): direct user to face & fingerprint setup
- return null;
+ return ActiveUnlockRequireBiometricSetup.class.getName();
}
}
diff --git a/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusUtils.java b/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusUtils.java
index 439f176..4ff2b87 100644
--- a/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusUtils.java
+++ b/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusUtils.java
@@ -242,6 +242,32 @@
}
}
+ /**
+ * Returns the summary of the active unlock preference when biometrics are needed to set up the
+ * feature.
+ */
+ @Nullable
+ public String getSummaryWhenBiometricSetupRequired() {
+ final boolean faceAllowed = Utils.hasFaceHardware(mContext);
+ final boolean fingerprintAllowed = Utils.hasFingerprintHardware(mContext);
+
+ int summaryRes = getSetupBiometricRes(faceAllowed, fingerprintAllowed);
+ return summaryRes == 0 ? null : mContext.getString(summaryRes);
+ }
+
+ @StringRes
+ private static int getSetupBiometricRes(boolean faceAllowed, boolean fingerprintAllowed) {
+ if (faceAllowed && fingerprintAllowed) {
+ return R.string.security_settings_activeunlock_require_face_fingerprint_setup_title;
+ } else if (faceAllowed) {
+ return R.string.security_settings_activeunlock_require_face_setup_title;
+ } else if (fingerprintAllowed) {
+ return R.string.security_settings_activeunlock_require_fingerprint_setup_title;
+ } else {
+ return 0;
+ }
+ }
+
private static String getFlagState() {
return DeviceConfig.getProperty(DeviceConfig.NAMESPACE_REMOTE_AUTH, CONFIG_FLAG_NAME);
}
diff --git a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
index 0a1d29d..1f91a46 100644
--- a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
+++ b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java
@@ -55,6 +55,7 @@
@VisibleForTesting
static final int CONFIRM_REQUEST = 2001;
private static final int CHOOSE_LOCK_REQUEST = 2002;
+ protected static final int ACTIVE_UNLOCK_REQUEST = 2003;
private static final String SAVE_STATE_CONFIRM_CREDETIAL = "confirm_credential";
private static final String DO_NOT_FINISH_ACTIVITY = "do_not_finish_activity";
@@ -68,8 +69,9 @@
private boolean mConfirmCredential;
@Nullable private FaceManager mFaceManager;
@Nullable private FingerprintManager mFingerprintManager;
- // Do not finish() if choosing/confirming credential, or showing fp/face settings
- private boolean mDoNotFinishActivity;
+ // Do not finish() if choosing/confirming credential, showing fp/face settings, or launching
+ // active unlock
+ protected boolean mDoNotFinishActivity;
@Nullable private String mRetryPreferenceKey = null;
@Nullable private Bundle mRetryPreferenceExtra = null;
@@ -132,7 +134,7 @@
}
}
- private boolean onRetryPreferenceTreeClick(Preference preference, final boolean retry) {
+ protected boolean onRetryPreferenceTreeClick(Preference preference, final boolean retry) {
final String key = preference.getKey();
final Context context = requireActivity().getApplicationContext();
@@ -323,6 +325,14 @@
return resId == 0 ? "" : getString(resId);
}
+ protected int getUserId() {
+ return mUserId;
+ }
+
+ protected long getGkPwHandle() {
+ return mGkPwHandle;
+ }
+
@NonNull
private String getUseClass2BiometricSummary() {
boolean isFaceAllowed = false;
diff --git a/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java b/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java
index a352e5a..d0e986f 100644
--- a/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java
+++ b/src/com/android/settings/biometrics/combination/CombinedBiometricSettings.java
@@ -15,9 +15,14 @@
*/
package com.android.settings.biometrics.combination;
+import static com.android.settings.biometrics.activeunlock.ActiveUnlockStatusPreferenceController.KEY_ACTIVE_UNLOCK_SETTINGS;
+import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
+
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
+import android.os.UserHandle;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
@@ -25,6 +30,7 @@
import com.android.settings.R;
import com.android.settings.biometrics.activeunlock.ActiveUnlockContentListener.OnContentChangedListener;
import com.android.settings.biometrics.activeunlock.ActiveUnlockDeviceNameListener;
+import com.android.settings.biometrics.activeunlock.ActiveUnlockRequireBiometricSetup;
import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
@@ -42,6 +48,7 @@
private static final String KEY_INTRO_PREFERENCE = "biometric_intro";
private ActiveUnlockStatusUtils mActiveUnlockStatusUtils;
+ private CombinedBiometricStatusUtils mCombinedBiometricStatusUtils;
@Nullable private ActiveUnlockDeviceNameListener mActiveUnlockDeviceNameListener;
@Override
@@ -55,6 +62,7 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActiveUnlockStatusUtils = new ActiveUnlockStatusUtils(getActivity());
+ mCombinedBiometricStatusUtils = new CombinedBiometricStatusUtils(getActivity(), mUserId);
if (mActiveUnlockStatusUtils.isAvailable()) {
updateUiForActiveUnlock();
}
@@ -122,6 +130,35 @@
}
@Override
+ protected boolean onRetryPreferenceTreeClick(Preference preference, final boolean retry) {
+ if (!mActiveUnlockStatusUtils.isAvailable()
+ || !KEY_ACTIVE_UNLOCK_SETTINGS.equals(preference.getKey())) {
+ return super.onRetryPreferenceTreeClick(preference, retry);
+ }
+ mDoNotFinishActivity = true;
+ Intent intent;
+ if (mActiveUnlockStatusUtils.useBiometricFailureLayout()
+ && mActiveUnlockDeviceNameListener != null
+ && !mActiveUnlockDeviceNameListener.hasEnrolled()
+ && !mCombinedBiometricStatusUtils.hasEnrolled()) {
+ intent = new Intent(getActivity(), ActiveUnlockRequireBiometricSetup.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ int userId = mUserId;
+ if (mUserId != UserHandle.USER_NULL) {
+ intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
+ }
+ intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGkPwHandle());
+ } else {
+ intent = mActiveUnlockStatusUtils.getIntent();
+ }
+ if (intent != null) {
+ startActivityForResult(intent, ACTIVE_UNLOCK_REQUEST);
+ }
+ return true;
+
+ }
+
+ @Override
protected String getUseAnyBiometricSummary() {
// either Active Unlock is not enabled or no device is enrolled.
if (mActiveUnlockDeviceNameListener == null
diff --git a/tests/robotests/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceControllerTest.java
index bf60d01..5219a3a 100644
--- a/tests/robotests/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/activeunlock/ActiveUnlockStatusPreferenceControllerTest.java
@@ -32,6 +32,7 @@
import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settings.testutils.ActiveUnlockTestUtils;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settingslib.RestrictedPreference;
@@ -162,9 +163,57 @@
assertThat(mPreference.getSummary().toString()).isEqualTo(summary);
}
+ @Test
+ public void biometricsNotSetUp_deviceNameIsNotSet_setupBiometricStringShown() {
+ ActiveUnlockTestUtils.enable(mContext, ActiveUnlockStatusUtils.BIOMETRIC_FAILURE_LAYOUT);
+ updateSummary("newSummary");
+ mController.displayPreference(mPreferenceScreen);
+
+ mController.onStart();
+ idleMainLooper();
+
+ assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(
+ R.string.security_settings_activeunlock_require_face_fingerprint_setup_title));
+ }
+
+ @Test
+ public void biometricNotSetUp_deviceNameIsSet_summaryShown() {
+ ActiveUnlockTestUtils.enable(mContext, ActiveUnlockStatusUtils.BIOMETRIC_FAILURE_LAYOUT);
+ String summary = "newSummary";
+ updateSummary(summary);
+ updateDeviceName("deviceName");
+ mController.displayPreference(mPreferenceScreen);
+
+ mController.onStart();
+ idleMainLooper();
+
+ assertThat(mPreference.getSummary()).isEqualTo(summary);
+ }
+
+ @Test
+ public void biometricSetUp_summaryShown() {
+ when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(true);
+ ActiveUnlockTestUtils.enable(mContext, ActiveUnlockStatusUtils.BIOMETRIC_FAILURE_LAYOUT);
+ String summary = "newSummary";
+ updateSummary(summary);
+ mController.displayPreference(mPreferenceScreen);
+
+ mController.onStart();
+ idleMainLooper();
+
+ assertThat(mPreference.getSummary()).isEqualTo(summary);
+ }
+
private void updateSummary(String summary) {
FakeContentProvider.setTileSummary(summary);
mContext.getContentResolver().notifyChange(FakeContentProvider.URI, null /* observer */);
idleMainLooper();
}
+
+ private void updateDeviceName(String deviceName) {
+ FakeContentProvider.setDeviceName(deviceName);
+ mContext.getContentResolver().notifyChange(FakeContentProvider.URI, null /* observer */);
+ idleMainLooper();
+ }
+
}