Skip to content

Commit

Permalink
Several fixes according to code review. Upgrade to full clone of andr…
Browse files Browse the repository at this point in the history
…oidx.biometic.
  • Loading branch information
exxbrain committed Oct 16, 2019
1 parent f7d75c9 commit d262c16
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 122 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@
}
}
}
}
}
10 changes: 10 additions & 0 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,19 @@
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
</config-file>

<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity
android:name="de.niklasmerz.cordova.biometric.BiometricActivity"
android:theme="@style/TransparentTheme"
android:exported="true" />
</config-file>

<framework src="src/android/build.gradle" custom="true" type="gradleReference"/>
<resource-file src="src/android/res/biometric_activity.xml" target="res/layout/biometric_activity.xml" />
<resource-file src="src/android/res/styles.xml" target="res/values/biometric-styles.xml" />
<resource-file src="src/android/android-biometric.aar" target="libs/android-biometric.aar" />
<source-file src="src/android/BiometricActivity.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
<source-file src="src/android/Fingerprint.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
<source-file src="src/android/PluginError.java" target-dir="src/de/niklasmerz/cordova/biometric"/>
</platform>
Expand Down
171 changes: 171 additions & 0 deletions src/android/BiometricActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package de.niklasmerz.cordova.biometric;

import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;

import com.exxbrain.android.biometric.BiometricPrompt;

import java.util.concurrent.Executor;

public class BiometricActivity extends AppCompatActivity {

private static final int REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS = 2;
private boolean mDeviceCredentialAllowed;
private String mTitle;
private String mDescription;
private String mSubtitile;
private String mFallbackButtonTitle;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setTitle(null);
int layout = getResources()
.getIdentifier("biometric_activity", "layout", getPackageName());
setContentView(layout);

Bundle extras = getIntent().getExtras();
mDeviceCredentialAllowed = !extras.getBoolean(Fingerprint.DISABLE_BACKUP);
mTitle = extras.getString(Fingerprint.TITLE);
mDescription = extras.getString(Fingerprint.DESCRIPTION);
mSubtitile = extras.getString(Fingerprint.SUBTITLE);
mFallbackButtonTitle = extras.getString(Fingerprint.FALLBACK_BUTTON_TITLE);

authenticate();

}

private void authenticate() {

Executor executor;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
executor = this.getMainExecutor();
} else {
final Handler handler = new Handler(Looper.getMainLooper());
executor = handler::post;
}

BiometricPrompt biometricPrompt =
new BiometricPrompt(this, executor, mAuthenticationCallback);

BiometricPrompt.PromptInfo.Builder promptInfoBuilder = new BiometricPrompt.PromptInfo.Builder()
.setTitle(mTitle)
.setSubtitle(mSubtitile)
.setDescription(mDescription);

if (mDeviceCredentialAllowed
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { // TODO: remove after fix https://issuetracker.google.com/issues/142740104
promptInfoBuilder.setDeviceCredentialAllowed(true);
} else {
promptInfoBuilder.setNegativeButtonText(mFallbackButtonTitle);
}

biometricPrompt.authenticate(promptInfoBuilder.build());
}

private BiometricPrompt.AuthenticationCallback mAuthenticationCallback =
new BiometricPrompt.AuthenticationCallback() {

@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
onError(errorCode, errString);
}

@Override
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
setResult(RESULT_OK);
finish();
}

@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
finishWithError(PluginError.BIOMETRIC_AUTHENTICATION_FAILED);
}
};


// TODO: remove after fix https://issuetracker.google.com/issues/142740104
private void showAuthenticationScreen() {
KeyguardManager keyguardManager = ContextCompat
.getSystemService(this, KeyguardManager.class);
if (keyguardManager == null
|| android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
return;
}
if (keyguardManager.isKeyguardSecure()) {
Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(mTitle, mDescription);
this.startActivityForResult(intent, REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS);
} else {
// Show a message that the user hasn't set up a lock screen.
finishWithError(PluginError.BIOMETRIC_SCREEN_GUARD_UNSECURED);
}
}

// TODO: remove after fix https://issuetracker.google.com/issues/142740104
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS) {
if (resultCode == Activity.RESULT_OK) {
finishWithSuccess();
} else {
finishWithError(PluginError.BIOMETRIC_PIN_OR_PATTERN_DISMISSED);
}
}
}

private void onError(int errorCode, @NonNull CharSequence errString) {

switch (errorCode)
{
case BiometricPrompt.ERROR_CANCELED:
finishWithError(PluginError.BIOMETRIC_FINGERPRINT_DISMISSED);
return;
case BiometricPrompt.ERROR_NEGATIVE_BUTTON:
// TODO: remove after fix https://issuetracker.google.com/issues/142740104
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P && mDeviceCredentialAllowed) {
showAuthenticationScreen();
return;
}
finishWithError(PluginError.BIOMETRIC_FINGERPRINT_DISMISSED);
break;
case BiometricPrompt.ERROR_LOCKOUT:
finishWithError(PluginError.BIOMETRIC_LOCKED_OUT.getValue(), errString.toString());
break;
case BiometricPrompt.ERROR_LOCKOUT_PERMANENT:
finishWithError(PluginError.BIOMETRIC_LOCKED_OUT_PERMANENT.getValue(), errString.toString());
break;
default:
finishWithError(errorCode, errString.toString());
}
}

private void finishWithSuccess() {
setResult(RESULT_OK);
finish();
}

private void finishWithError(PluginError error) {
finishWithError(error.getValue(), error.getMessage());
}

private void finishWithError(int code, String message) {
Intent data = new Intent();
data.putExtra("code", code);
data.putExtra("message", message);
setResult(RESULT_CANCELED, data);
finish();
}
}
Loading

0 comments on commit d262c16

Please sign in to comment.