From f84e944181562207e62a66fb1fed247f2fd381bd Mon Sep 17 00:00:00 2001
From: NekoInverter <42698724+NekoInverter@users.noreply.github.com>
Date: Mon, 23 Mar 2020 20:49:07 +0800
Subject: [PATCH] Use BiometricPrompt
---
app/build.gradle | 1 +
.../ehviewer/ui/SetSecurityActivity.java | 19 +--
.../ehviewer/ui/scene/SecurityScene.java | 109 +++++-------------
.../res/layout-land/activity_set_security.xml | 24 ++--
.../main/res/layout/activity_set_security.xml | 25 ++--
.../main/res/layout/scene_cookie_sign_in.xml | 13 +--
app/src/main/res/layout/scene_security.xml | 20 +---
7 files changed, 58 insertions(+), 153 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 417c60195..764934617 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -78,6 +78,7 @@ tasks.withType(JavaCompile) {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.2.0-alpha03'
+ implementation 'androidx.biometric:biometric:1.0.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'
implementation 'com.google.android.material:material:1.1.0'
diff --git a/app/src/main/java/com/hippo/ehviewer/ui/SetSecurityActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/SetSecurityActivity.java
index 3202e8dc1..d863e5c75 100755
--- a/app/src/main/java/com/hippo/ehviewer/ui/SetSecurityActivity.java
+++ b/app/src/main/java/com/hippo/ehviewer/ui/SetSecurityActivity.java
@@ -16,8 +16,6 @@
package com.hippo.ehviewer.ui;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.MenuItem;
@@ -25,7 +23,7 @@ import android.view.View;
import android.widget.CheckBox;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
+import androidx.biometric.BiometricManager;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
@@ -44,16 +42,6 @@ public class SetSecurityActivity extends ToolbarActivity implements View.OnClick
@Nullable
private CheckBox mFingerprint;
- @RequiresApi(api = Build.VERSION_CODES.M)
- public static boolean hasEnrolledFingerprints(FingerprintManager fingerprintManager) {
- try {
- return fingerprintManager.isHardwareDetected()
- && fingerprintManager.hasEnrolledFingerprints();
- } catch (Throwable e) {
- return false;
- }
- }
-
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -72,10 +60,7 @@ public class SetSecurityActivity extends ToolbarActivity implements View.OnClick
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
- FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
- // The line below prevents the false positive inspection from Android Studio
- // noinspection ResourceType
- if (fingerprintManager != null && hasEnrolledFingerprints(fingerprintManager)) {
+ if (BiometricManager.from(this).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) {
mFingerprint.setVisibility(View.VISIBLE);
mFingerprint.setChecked(Settings.getEnableFingerprint());
}
diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java
index 5261b0af8..0a98139c8 100755
--- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java
+++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java
@@ -19,59 +19,43 @@ package com.hippo.ehviewer.ui.scene;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
-import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.Bundle;
-import android.os.CancellationSignal;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.biometric.BiometricManager;
+import androidx.biometric.BiometricPrompt;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.ui.MainActivity;
-import com.hippo.ehviewer.ui.SetSecurityActivity;
import com.hippo.hardware.ShakeDetector;
import com.hippo.widget.lockpattern.LockPatternUtils;
import com.hippo.widget.lockpattern.LockPatternView;
-import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.ObjectUtils;
import com.hippo.yorozuya.ViewUtils;
import java.util.List;
+import java.util.concurrent.Executors;
public class SecurityScene extends SolidScene implements
LockPatternView.OnPatternListener, ShakeDetector.OnShakeListener {
private static final int MAX_RETRY_TIMES = 5;
- private static final long ERROR_TIMEOUT_MILLIS = 1200;
- private static final long SUCCESS_DELAY_MILLIS = 100;
-
private static final String KEY_RETRY_TIMES = "retry_times";
@Nullable
private LockPatternView mPatternView;
- private ImageView mFingerprintIcon;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private ShakeDetector mShakeDetector;
- @Nullable
- private FingerprintManager mFingerprintManager;
-
- private CancellationSignal mFingerprintCancellationSignal;
private int mRetryTimes;
- private Runnable mResetFingerprintRunnable = new Runnable() {
- @Override
- public void run() {
- if (mFingerprintIcon != null)
- mFingerprintIcon.setImageResource(R.drawable.ic_fp_40px);
- }
- };
@Override
public boolean needShowLeftDrawer() {
@@ -82,8 +66,7 @@ public class SecurityScene extends SolidScene implements
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Context context = getContext2();
- AssertUtils.assertNotNull(context);
+ Context context = requireContext();
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if (null != mSensorManager) {
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -92,9 +75,6 @@ public class SecurityScene extends SolidScene implements
mShakeDetector.setOnShakeListener(this);
}
}
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- mFingerprintManager = context.getSystemService(FingerprintManager.class);
- }
if (null == savedInstanceState) {
mRetryTimes = MAX_RETRY_TIMES;
@@ -121,35 +101,29 @@ public class SecurityScene extends SolidScene implements
}
if (isFingerprintAuthAvailable()) {
- mFingerprintCancellationSignal = new CancellationSignal();
- // The line below prevents the false positive inspection from Android Studio
- // noinspection ResourceType
- mFingerprintManager.authenticate(null, mFingerprintCancellationSignal, 0,
- new FingerprintManager.AuthenticationCallback() {
- @Override
- public void onAuthenticationError(int errMsgId, CharSequence errString) {
- fingerprintError(true);
- }
+ BiometricPrompt biometricPrompt = new BiometricPrompt(this, Executors.newSingleThreadExecutor(), new BiometricPrompt.AuthenticationCallback() {
+ @Override
+ public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
+ super.onAuthenticationError(errorCode, errString);
+ }
- @Override
- public void onAuthenticationFailed() {
- fingerprintError(false);
- }
+ @Override
+ public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
+ startSceneForCheckStep(CHECK_STEP_SECURITY, getArguments());
+ finish();
+ super.onAuthenticationSucceeded(result);
+ }
- @Override
- public void onAuthenticationSucceeded(
- FingerprintManager.AuthenticationResult result) {
- mFingerprintIcon.setImageResource(R.drawable.fingerprint_success);
- mFingerprintIcon.postDelayed(new Runnable() {
- @Override
- public void run() {
- startSceneForCheckStep(CHECK_STEP_SECURITY, getArguments());
- finish();
- }
- }, SUCCESS_DELAY_MILLIS);
-
- }
- }, null);
+ @Override
+ public void onAuthenticationFailed() {
+ super.onAuthenticationFailed();
+ }
+ });
+ BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
+ .setTitle(getString(R.string.app_name))
+ .setNegativeButtonText(getString(android.R.string.cancel))
+ .build();
+ biometricPrompt.authenticate(promptInfo);
}
}
@@ -160,10 +134,6 @@ public class SecurityScene extends SolidScene implements
if (null != mShakeDetector) {
mSensorManager.unregisterListener(mShakeDetector);
}
- if (isFingerprintAuthAvailable() && mFingerprintCancellationSignal != null) {
- mFingerprintCancellationSignal.cancel();
- mFingerprintCancellationSignal = null;
- }
}
@Override
@@ -180,12 +150,6 @@ public class SecurityScene extends SolidScene implements
mPatternView = (LockPatternView) ViewUtils.$$(view, R.id.pattern_view);
mPatternView.setOnPatternListener(this);
-
- mFingerprintIcon = (ImageView) ViewUtils.$$(view, R.id.fingerprint_icon);
- if (Settings.getEnableFingerprint() && isFingerprintAuthAvailable()) {
- mFingerprintIcon.setVisibility(View.VISIBLE);
- mFingerprintIcon.setImageResource(R.drawable.ic_fp_40px);
- }
return view;
}
@@ -244,27 +208,8 @@ public class SecurityScene extends SolidScene implements
}
private boolean isFingerprintAuthAvailable() {
- // The line below prevents the false positive inspection from Android Studio
- // noinspection ResourceType
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Settings.getEnableFingerprint()
- && mFingerprintManager != null
- && SetSecurityActivity.hasEnrolledFingerprints(mFingerprintManager);
- }
-
- private void fingerprintError(boolean unrecoverable) {
- // Do not decrease mRetryTimes here since Android system will handle it :)
- mFingerprintIcon.setImageResource(R.drawable.fingerprint_error);
- mFingerprintIcon.removeCallbacks(mResetFingerprintRunnable);
- if (unrecoverable) {
- mFingerprintIcon.postDelayed(new Runnable() {
- @Override
- public void run() {
- mFingerprintIcon.setVisibility(View.INVISIBLE);
- }
- }, ERROR_TIMEOUT_MILLIS);
- } else {
- mFingerprintIcon.postDelayed(mResetFingerprintRunnable, ERROR_TIMEOUT_MILLIS);
- }
+ && BiometricManager.from(requireContext()).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
}
}
diff --git a/app/src/main/res/layout-land/activity_set_security.xml b/app/src/main/res/layout-land/activity_set_security.xml
index 3ed310944..84bec4338 100755
--- a/app/src/main/res/layout-land/activity_set_security.xml
+++ b/app/src/main/res/layout-land/activity_set_security.xml
@@ -50,11 +50,10 @@
android:text="@string/enable_fingerprint" />
-
-
+ android:text="@string/set" />
+
diff --git a/app/src/main/res/layout/activity_set_security.xml b/app/src/main/res/layout/activity_set_security.xml
index 47cd459a6..f8c2673e3 100755
--- a/app/src/main/res/layout/activity_set_security.xml
+++ b/app/src/main/res/layout/activity_set_security.xml
@@ -63,29 +63,26 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingTop="4dp"
android:paddingRight="12dp"
android:paddingBottom="4dp">
-
-
+ android:text="@string/set" />
+
diff --git a/app/src/main/res/layout/scene_cookie_sign_in.xml b/app/src/main/res/layout/scene_cookie_sign_in.xml
index 2a95008da..f42f687c5 100644
--- a/app/src/main/res/layout/scene_cookie_sign_in.xml
+++ b/app/src/main/res/layout/scene_cookie_sign_in.xml
@@ -125,25 +125,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingTop="4dp"
android:paddingRight="12dp"
android:paddingBottom="4dp">
-
-
diff --git a/app/src/main/res/layout/scene_security.xml b/app/src/main/res/layout/scene_security.xml
index 980ba2dea..3f7c37033 100755
--- a/app/src/main/res/layout/scene_security.xml
+++ b/app/src/main/res/layout/scene_security.xml
@@ -26,25 +26,11 @@
app:maxHeight="360dp"
app:maxWidth="320dp">
-
+ android:layout_height="wrap_content" />
-
-
-
-
-