Skip to content
This repository has been archived by the owner on Aug 26, 2019. It is now read-only.

Improved fingerprint support #246

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions app/src/main/java/com/hippo/ehviewer/ui/SetSecurityActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,17 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {

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.hasEnrolledFingerprints()) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method might make the code clean.

@RequiresApi(api = Build.VERSION_CODES.M)
public static boolean hasEnrolledFingerprints(FingerprintManager fp) {
    try {
        return (fp != null) && fp.hasEnrolledFingerprints();
    } catch (SecurityException e) {
        // Some Samsung devices throw this on hasEnrolledFingerprints().
        return false;
    }
}

mFingerprint.setVisibility(View.VISIBLE);
mFingerprint.setChecked(Settings.getEnableFingerprint());
try {
// The line below prevents the false positive inspection from Android Studio
// noinspection ResourceType
if (fingerprintManager.isHardwareDetected() &&
fingerprintManager.hasEnrolledFingerprints()) {
mFingerprint.setVisibility(View.VISIBLE);
mFingerprint.setChecked(Settings.getEnableFingerprint());
}
} catch (SecurityException e) {
// empty
// Some Samsung devices throw this on hasEnrolledFingerprints().
}
}

Expand Down
38 changes: 29 additions & 9 deletions app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
Expand All @@ -47,13 +48,15 @@ public class SecurityScene extends SolidScene implements

private static final int MAX_RETRY_TIMES = 5;
private static final long ERROR_TIMEOUT_MILLIS = 1200;
private static final long UNRECOVERABLE_ERROR_TIMEOUT_MILLIS = ERROR_TIMEOUT_MILLIS * 2;
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 TextView mFingerprintText;

private SensorManager mSensorManager;
private Sensor mAccelerometer;
Expand Down Expand Up @@ -111,14 +114,17 @@ public void onResume() {
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}

if (isFingerprintAuthAvailable()) {
// Redundant SDK version checking prevents false positive inspection
if (isFingerprintAuthAvailable() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
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) {
mFingerprintText.setText(errString);
mFingerprintText.setVisibility(View.VISIBLE);
fingerprintError(true);
}

Expand Down Expand Up @@ -151,7 +157,9 @@ public void onPause() {
if (null != mShakeDetector) {
mSensorManager.unregisterListener(mShakeDetector);
}
if (isFingerprintAuthAvailable() && mFingerprintCancellationSignal != null) {
// Redundant SDK version checking prevents false positive inspection
if (isFingerprintAuthAvailable() && mFingerprintCancellationSignal != null
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mFingerprintCancellationSignal.cancel();
mFingerprintCancellationSignal = null;
}
Expand All @@ -173,9 +181,11 @@ public View onCreateView2(LayoutInflater inflater,
mPatternView.setOnPatternListener(this);

mFingerprintIcon = (ImageView) ViewUtils.$$(view, R.id.fingerprint_icon);
mFingerprintText = (TextView) ViewUtils.$$(view, R.id.fingerprint_text);
if (Settings.getEnableFingerprint() && isFingerprintAuthAvailable()) {
mFingerprintIcon.setVisibility(View.VISIBLE);
mFingerprintIcon.setImageResource(R.drawable.ic_fp_40px);
mFingerprintText.setVisibility(View.INVISIBLE);
}
return view;
}
Expand Down Expand Up @@ -234,18 +244,25 @@ public void onShake(int count) {
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
&& mFingerprintManager.isHardwareDetected()
&& mFingerprintManager.hasEnrolledFingerprints();
try {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Settings.getEnableFingerprint()
&& mFingerprintManager != null
&& mFingerprintManager.isHardwareDetected()
&& mFingerprintManager.hasEnrolledFingerprints();
} catch (SecurityException e) {
// Some Samsung devices throw this on hasEnrolledFingerprints().
return false;
}
}

private Runnable mResetFingerprintRunnable = new Runnable() {
@Override
public void run() {
if (mFingerprintIcon != null)
mFingerprintIcon.setImageResource(R.drawable.ic_fp_40px);
if (mFingerprintText != null)
mFingerprintText.setVisibility(View.INVISIBLE);
}
};

Expand All @@ -257,9 +274,12 @@ private void fingerprintError(boolean unrecoverable) {
mFingerprintIcon.postDelayed(new Runnable() {
@Override
public void run() {
mFingerprintIcon.setVisibility(View.INVISIBLE);
if (mFingerprintIcon != null)
mFingerprintIcon.setVisibility(View.INVISIBLE);
if (mFingerprintText != null)
mFingerprintText.setVisibility(View.INVISIBLE);
}
}, ERROR_TIMEOUT_MILLIS);
}, UNRECOVERABLE_ERROR_TIMEOUT_MILLIS);
} else {
mFingerprintIcon.postDelayed(mResetFingerprintRunnable, ERROR_TIMEOUT_MILLIS);
}
Expand Down
12 changes: 10 additions & 2 deletions app/src/main/res/layout/scene_security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
android:layout_gravity="center"
android:layout_margin="32dp"
app:maxWidth="320dp"
app:maxHeight="360dp">
app:maxHeight="380dp">

<LinearLayout
android:layout_width="wrap_content"
Expand All @@ -41,10 +41,18 @@

<ImageView
android:id="@+id/fingerprint_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_fp_40px"
android:layout_gravity="center_horizontal"
android:visibility="gone" />

<TextView
android:id="@+id/fingerprint_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_fp_40px"
android:layout_gravity="center_horizontal"
android:textColor="@color/fingerprint_error_text"
android:visibility="gone" />

</LinearLayout>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/colors.xml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,7 @@
<color name="lock_pattern_view_success_color">@color/colorPrimary</color>
<color name="lock_pattern_view_error_color">@color/red_500</color>

<!-- Fingerprint -->
<color name="fingerprint_error_text">@color/red_500</color>

</resources>