Separate FingerprintHelper and AuthDialog

This commit is contained in:
topjohnwu 2019-01-31 00:05:59 -05:00
parent cfb0a3ba2a
commit 4091687733
8 changed files with 103 additions and 71 deletions

View File

@ -1,2 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.topjohnwu.magisk.core" />
package="com.topjohnwu.magisk.core" >
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
</manifest>

View File

@ -1,26 +1,17 @@
package com.topjohnwu.magisk.utils;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.view.Gravity;
import android.widget.Toast;
import com.topjohnwu.magisk.App;
import com.topjohnwu.magisk.Config;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.dialogs.CustomAlertDialog;
import java.security.KeyStore;
@ -35,7 +26,7 @@ public abstract class FingerprintHelper {
private Cipher cipher;
private CancellationSignal cancel;
public static boolean useFingerPrint() {
public static boolean useFingerprint() {
boolean fp = Config.get(Config.Key.SU_FINGERPRINT);
if (fp && !canUseFingerprint()) {
Config.set(Config.Key.SU_FINGERPRINT, false);
@ -52,56 +43,6 @@ public abstract class FingerprintHelper {
return km.isKeyguardSecure() && fm != null && fm.isHardwareDetected() && fm.hasEnrolledFingerprints();
}
public static void showAuthDialog(Activity activity, Runnable onSuccess) {
CustomAlertDialog dialog = new CustomAlertDialog(activity);
CustomAlertDialog.ViewHolder vh = dialog.getViewHolder();
try {
FingerprintHelper helper = new FingerprintHelper() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
vh.messageView.setTextColor(Color.RED);
vh.messageView.setText(errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
vh.messageView.setTextColor(Color.RED);
vh.messageView.setText(helpString);
}
@Override
public void onAuthenticationFailed() {
vh.messageView.setTextColor(Color.RED);
vh.messageView.setText(R.string.auth_fail);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
dialog.dismiss();
onSuccess.run();
}
};
Drawable fingerprint = activity.getResources().getDrawable(R.drawable.ic_fingerprint);
fingerprint.setBounds(0, 0, Utils.dpInPx(50), Utils.dpInPx(50));
Resources.Theme theme = activity.getTheme();
TypedArray ta = theme.obtainStyledAttributes(new int[] {R.attr.imageColorTint});
fingerprint.setTint(ta.getColor(0, Color.GRAY));
ta.recycle();
vh.messageView.setCompoundDrawables(null, null, null, fingerprint);
vh.messageView.setCompoundDrawablePadding(Utils.dpInPx(20));
vh.messageView.setGravity(Gravity.CENTER);
dialog.setMessage(R.string.auth_fingerprint)
.setNegativeButton(R.string.close, (d, w) -> helper.cancel())
.setOnCancelListener(d -> helper.cancel())
.show();
helper.authenticate();
} catch (Exception e) {
e.printStackTrace();
Utils.toast(R.string.auth_fail, Toast.LENGTH_SHORT);
}
}
protected FingerprintHelper() throws Exception {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
manager = App.self.getSystemService(FingerprintManager.class);

View File

@ -5,7 +5,6 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application

View File

@ -148,7 +148,7 @@ public class SuRequestActivity extends BaseActivity {
}
};
boolean useFP = FingerprintHelper.useFingerPrint();
boolean useFP = FingerprintHelper.useFingerprint();
if (useFP) {
try {

View File

@ -15,6 +15,7 @@ import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.database.MagiskDB;
import com.topjohnwu.magisk.dialogs.CustomAlertDialog;
import com.topjohnwu.magisk.dialogs.FingerprintAuthDialog;
import com.topjohnwu.magisk.uicomponents.ExpandableViewHolder;
import com.topjohnwu.magisk.uicomponents.SnackbarMaker;
import com.topjohnwu.magisk.utils.FingerprintHelper;
@ -85,12 +86,12 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
dbHelper.updatePolicy(policy);
}
};
if (FingerprintHelper.useFingerPrint()) {
if (FingerprintHelper.useFingerprint()) {
holder.masterSwitch.setChecked(!isChecked);
FingerprintHelper.showAuthDialog((Activity) v.getContext(), () -> {
new FingerprintAuthDialog((Activity) v.getContext(), () -> {
holder.masterSwitch.setChecked(isChecked);
r.run();
});
}).show();
} else {
r.run();
}

View File

@ -22,9 +22,9 @@ public class CustomAlertDialog extends AlertDialog.Builder {
private DialogInterface.OnClickListener positiveListener;
private DialogInterface.OnClickListener negativeListener;
private DialogInterface.OnClickListener neutralListener;
private AlertDialog dialog;
private ViewHolder vh;
protected AlertDialog dialog;
protected ViewHolder vh;
public class ViewHolder {
@BindView(R.id.dialog_layout) public LinearLayout dialogLayout;

View File

@ -0,0 +1,88 @@
package com.topjohnwu.magisk.dialogs;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.view.Gravity;
import android.widget.Toast;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.Utils;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
@TargetApi(Build.VERSION_CODES.M)
public class FingerprintAuthDialog extends CustomAlertDialog {
private Runnable callback;
private DialogFingerprintHelper helper;
public FingerprintAuthDialog(@NonNull Activity activity, Runnable onSuccess) {
super(activity);
callback = onSuccess;
Drawable fingerprint = activity.getResources().getDrawable(R.drawable.ic_fingerprint);
fingerprint.setBounds(0, 0, Utils.dpInPx(50), Utils.dpInPx(50));
Resources.Theme theme = activity.getTheme();
TypedArray ta = theme.obtainStyledAttributes(new int[] {R.attr.imageColorTint});
fingerprint.setTint(ta.getColor(0, Color.GRAY));
ta.recycle();
vh.messageView.setCompoundDrawables(null, null, null, fingerprint);
vh.messageView.setCompoundDrawablePadding(Utils.dpInPx(20));
vh.messageView.setGravity(Gravity.CENTER);
setMessage(R.string.auth_fingerprint);
setNegativeButton(R.string.close, (d, w) -> helper.cancel());
setOnCancelListener(d -> helper.cancel());
try {
helper = new DialogFingerprintHelper();
} catch (Exception ignored) {}
}
@Override
public AlertDialog show() {
create();
if (helper == null) {
dialog.dismiss();
Utils.toast(R.string.auth_fail, Toast.LENGTH_SHORT);
} else {
helper.authenticate();
dialog.show();
}
return dialog;
}
class DialogFingerprintHelper extends FingerprintHelper {
DialogFingerprintHelper() throws Exception {}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
vh.messageView.setTextColor(Color.RED);
vh.messageView.setText(errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
vh.messageView.setTextColor(Color.RED);
vh.messageView.setText(helpString);
}
@Override
public void onAuthenticationFailed() {
vh.messageView.setTextColor(Color.RED);
vh.messageView.setText(R.string.auth_fail);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
dismiss();
callback.run();
}
}
}

View File

@ -13,6 +13,7 @@ import com.topjohnwu.magisk.Config;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.components.BasePreferenceFragment;
import com.topjohnwu.magisk.dialogs.FingerprintAuthDialog;
import com.topjohnwu.magisk.tasks.CheckUpdates;
import com.topjohnwu.magisk.utils.AppUtils;
import com.topjohnwu.magisk.utils.DownloadApp;
@ -46,7 +47,7 @@ public class SettingsFragment extends BasePreferenceFragment implements Topic.Su
boolean showSuperuser = Utils.showSuperUser();
app.prefs.edit()
.putBoolean(Config.Key.SU_FINGERPRINT, FingerprintHelper.useFingerPrint())
.putBoolean(Config.Key.SU_FINGERPRINT, FingerprintHelper.useFingerprint())
.apply();
PreferenceScreen prefScreen = getPreferenceScreen();
@ -217,10 +218,10 @@ public class SettingsFragment extends BasePreferenceFragment implements Topic.Su
case Config.Key.SU_FINGERPRINT:
boolean checked = ((SwitchPreferenceCompat) preference).isChecked();
((SwitchPreferenceCompat) preference).setChecked(!checked);
FingerprintHelper.showAuthDialog(requireActivity(), () -> {
new FingerprintAuthDialog(requireActivity(), () -> {
((SwitchPreferenceCompat) preference).setChecked(checked);
Config.set(key, checked);
});
}).show();
break;
}
return true;