Pass Timeout back to upper biometric preference am: 52a46d0a85
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/22379152 Change-Id: I19bc33b58f8b036f7b52b2820e7154d3e8955379 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -26,6 +26,9 @@ import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.app.UnlaunchableAppActivity;
|
||||
import com.android.settings.core.SettingsBaseActivity;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
@@ -49,15 +52,23 @@ public class BiometricNavigationUtils {
|
||||
*
|
||||
* @param className The class name of Settings screen to launch.
|
||||
* @param extras Extras to put into the launching {@link Intent}.
|
||||
* @param launcher Launcher to launch activity if non-quiet mode
|
||||
* @return true if the Settings screen is launching.
|
||||
*/
|
||||
public boolean launchBiometricSettings(Context context, String className, Bundle extras) {
|
||||
public boolean launchBiometricSettings(Context context, String className, Bundle extras,
|
||||
@Nullable ActivityResultLauncher<Intent> launcher) {
|
||||
final Intent quietModeDialogIntent = getQuietModeDialogIntent(context);
|
||||
if (quietModeDialogIntent != null) {
|
||||
context.startActivity(quietModeDialogIntent);
|
||||
return false;
|
||||
}
|
||||
context.startActivity(getSettingsPageIntent(className, extras));
|
||||
|
||||
final Intent settingsPageIntent = getSettingsPageIntent(className, extras);
|
||||
if (launcher != null) {
|
||||
launcher.launch(settingsPageIntent);
|
||||
} else {
|
||||
context.startActivity(settingsPageIntent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -17,10 +17,14 @@
|
||||
package com.android.settings.biometrics;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
@@ -29,6 +33,8 @@ import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public abstract class BiometricStatusPreferenceController extends BasePreferenceController {
|
||||
|
||||
protected final UserManager mUm;
|
||||
@@ -39,6 +45,8 @@ public abstract class BiometricStatusPreferenceController extends BasePreference
|
||||
|
||||
private final BiometricNavigationUtils mBiometricNavigationUtils;
|
||||
private final ActiveUnlockStatusUtils mActiveUnlockStatusUtils;
|
||||
@NonNull private WeakReference<ActivityResultLauncher<Intent>> mLauncherWeakReference =
|
||||
new WeakReference<>(null);
|
||||
|
||||
/**
|
||||
* @return true if the controller should be shown exclusively.
|
||||
@@ -118,14 +126,31 @@ public abstract class BiometricStatusPreferenceController extends BasePreference
|
||||
preference.setSummary(getSummaryText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ActivityResultLauncher that will be used later during handlePreferenceTreeClick()
|
||||
*
|
||||
* @param preference the preference being compared
|
||||
* @param launcher the ActivityResultLauncher
|
||||
* @return {@code true} if matched preference.
|
||||
*/
|
||||
public boolean setPreferenceTreeClickLauncher(@NonNull Preference preference,
|
||||
@Nullable ActivityResultLauncher<Intent> launcher) {
|
||||
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mLauncherWeakReference = new WeakReference<>(launcher);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||
return super.handlePreferenceTreeClick(preference);
|
||||
}
|
||||
|
||||
return mBiometricNavigationUtils.launchBiometricSettings(
|
||||
preference.getContext(), getSettingsClassName(), preference.getExtras());
|
||||
return mBiometricNavigationUtils.launchBiometricSettings(preference.getContext(),
|
||||
getSettingsClassName(), preference.getExtras(), mLauncherWeakReference.get());
|
||||
}
|
||||
|
||||
protected int getUserId() {
|
||||
|
@@ -33,6 +33,9 @@ import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
@@ -42,14 +45,19 @@ import androidx.preference.Preference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.biometrics.BiometricStatusPreferenceController;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.biometrics.BiometricsSplitScreenDialog;
|
||||
import com.android.settings.core.SettingsBaseActivity;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.transition.SettingsTransitionHelper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base fragment with the confirming credential functionality for combined biometrics settings.
|
||||
*/
|
||||
@@ -78,6 +86,18 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
|
||||
@Nullable private String mRetryPreferenceKey = null;
|
||||
@Nullable private Bundle mRetryPreferenceExtra = null;
|
||||
|
||||
private final ActivityResultLauncher<Intent> mFaceOrFingerprintPreferenceLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
|
||||
this::onFaceOrFingerprintPreferenceResult);
|
||||
|
||||
private void onFaceOrFingerprintPreferenceResult(@Nullable ActivityResult result) {
|
||||
if (result != null && result.getResultCode() == BiometricEnrollBase.RESULT_TIMEOUT) {
|
||||
// When "Face Unlock" or "Fingerprint Unlock" is closed due to entering onStop(),
|
||||
// "Face & Fingerprint Unlock" shall also close itself and back to "Security" page.
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
@@ -165,7 +185,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
|
||||
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
||||
extras.putInt(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId);
|
||||
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge);
|
||||
super.onPreferenceTreeClick(preference);
|
||||
onFaceOrFingerprintPreferenceTreeClick(preference);
|
||||
} catch (IllegalStateException e) {
|
||||
if (retry) {
|
||||
mRetryPreferenceKey = preference.getKey();
|
||||
@@ -200,7 +220,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
|
||||
final Bundle extras = preference.getExtras();
|
||||
extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
||||
extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge);
|
||||
super.onPreferenceTreeClick(preference);
|
||||
onFaceOrFingerprintPreferenceTreeClick(preference);
|
||||
} catch (IllegalStateException e) {
|
||||
if (retry) {
|
||||
mRetryPreferenceKey = preference.getKey();
|
||||
@@ -224,6 +244,33 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
|
||||
return BiometricUtils.requestGatekeeperHat(context, gkPwHandle, userId, challenge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle preference tree click action for "Face Unlock" or "Fingerprint Unlock" with a launcher
|
||||
* because "Face & Fingerprint Unlock" has to close itself when it gets a specific activity
|
||||
* error code.
|
||||
*
|
||||
* @param preference "Face Unlock" or "Fingerprint Unlock" preference.
|
||||
*/
|
||||
private void onFaceOrFingerprintPreferenceTreeClick(@NonNull Preference preference) {
|
||||
Collection<List<AbstractPreferenceController>> controllers = getPreferenceControllers();
|
||||
for (List<AbstractPreferenceController> controllerList : controllers) {
|
||||
for (AbstractPreferenceController controller : controllerList) {
|
||||
if (controller instanceof BiometricStatusPreferenceController) {
|
||||
final BiometricStatusPreferenceController biometricController =
|
||||
(BiometricStatusPreferenceController) controller;
|
||||
if (biometricController.setPreferenceTreeClickLauncher(preference,
|
||||
mFaceOrFingerprintPreferenceLauncher)) {
|
||||
if (biometricController.handlePreferenceTreeClick(preference)) {
|
||||
writePreferenceClickMetric(preference);
|
||||
}
|
||||
biometricController.setPreferenceTreeClickLauncher(preference, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
return onRetryPreferenceTreeClick(preference, true)
|
||||
|
@@ -325,6 +325,8 @@ public class FaceSettings extends DashboardFragment {
|
||||
mFaceManager.revokeChallenge(mSensorId, mUserId, mChallenge);
|
||||
mToken = null;
|
||||
}
|
||||
// Let parent "Face & Fingerprint Unlock" can use this error code to close itself.
|
||||
setResult(RESULT_TIMEOUT);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
@@ -669,6 +669,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mIsEnrolling) {
|
||||
setResult(RESULT_TIMEOUT);
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
@@ -874,6 +875,12 @@ public class FingerprintSettings extends SubSettings {
|
||||
} else if (requestCode == AUTO_ADD_FIRST_FINGERPRINT_REQUEST) {
|
||||
if (resultCode != RESULT_FINISHED || data == null) {
|
||||
Log.d(TAG, "Add first fingerprint, fail or null data, result:" + resultCode);
|
||||
if (resultCode == BiometricEnrollBase.RESULT_TIMEOUT) {
|
||||
// If "Fingerprint Unlock" is closed because of timeout, notify result code
|
||||
// back because "Face & Fingerprint Unlock" has to close itself for timeout
|
||||
// case.
|
||||
setResult(resultCode);
|
||||
}
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -33,6 +34,7 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
@@ -55,6 +57,8 @@ public class BiometricNavigationUtilsTest {
|
||||
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private ActivityResultLauncher<Intent> mLauncher;
|
||||
private Context mContext;
|
||||
private BiometricNavigationUtils mBiometricNavigationUtils;
|
||||
|
||||
@@ -72,7 +76,7 @@ public class BiometricNavigationUtilsTest {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(true);
|
||||
|
||||
mBiometricNavigationUtils.launchBiometricSettings(mContext, SETTINGS_CLASS_NAME,
|
||||
Bundle.EMPTY);
|
||||
Bundle.EMPTY, null);
|
||||
|
||||
assertQuietModeDialogLaunchRequested();
|
||||
}
|
||||
@@ -82,7 +86,17 @@ public class BiometricNavigationUtilsTest {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(true);
|
||||
|
||||
assertThat(mBiometricNavigationUtils.launchBiometricSettings(
|
||||
mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY)).isFalse();
|
||||
mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY, null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchBiometricSettings_quietMode_withLauncher_notThroughLauncher() {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(true);
|
||||
|
||||
mBiometricNavigationUtils.launchBiometricSettings(mContext, SETTINGS_CLASS_NAME,
|
||||
Bundle.EMPTY, mLauncher);
|
||||
|
||||
verify(mLauncher, never()).launch(any(Intent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,7 +104,7 @@ public class BiometricNavigationUtilsTest {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
|
||||
mBiometricNavigationUtils.launchBiometricSettings(
|
||||
mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY);
|
||||
mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY, null);
|
||||
|
||||
assertSettingsPageLaunchRequested(false /* shouldContainExtras */);
|
||||
}
|
||||
@@ -100,7 +114,7 @@ public class BiometricNavigationUtilsTest {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
|
||||
assertThat(mBiometricNavigationUtils.launchBiometricSettings(
|
||||
mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY)).isTrue();
|
||||
mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY, null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,17 +122,29 @@ public class BiometricNavigationUtilsTest {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
|
||||
final Bundle extras = createNotEmptyExtras();
|
||||
mBiometricNavigationUtils.launchBiometricSettings(mContext, SETTINGS_CLASS_NAME, extras);
|
||||
mBiometricNavigationUtils.launchBiometricSettings(
|
||||
mContext, SETTINGS_CLASS_NAME, extras, null);
|
||||
|
||||
assertSettingsPageLaunchRequested(true /* shouldContainExtras */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchBiometricSettings_noQuietMode_withLauncher_launchesThroughLauncher() {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
|
||||
final Bundle extras = createNotEmptyExtras();
|
||||
mBiometricNavigationUtils.launchBiometricSettings(
|
||||
mContext, SETTINGS_CLASS_NAME, extras, mLauncher);
|
||||
|
||||
verify(mLauncher).launch(any(Intent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchBiometricSettings_noQuietMode_withExtras_returnsTrue() {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
|
||||
assertThat(mBiometricNavigationUtils.launchBiometricSettings(
|
||||
mContext, SETTINGS_CLASS_NAME, createNotEmptyExtras())).isTrue();
|
||||
mContext, SETTINGS_CLASS_NAME, createNotEmptyExtras(), null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user