Skip to content

Commit b586258

Browse files
committed
Support Biometric api
1 parent 47a03f2 commit b586258

File tree

17 files changed

+666
-434
lines changed

17 files changed

+666
-434
lines changed

app/src/main/java/com/surcumference/fingerprint/Lang.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ public static String getString(int res) {
117117
return tr("显示指纹图标", "顯示指紋圖標", "Fingerprint Icon");
118118
case R.id.settings_title_donate:
119119
return tr("赞助我", "贊助我", "Donate me");
120+
case R.id.settings_title_advance:
121+
return tr("通用设置", "一般选项", "General");
122+
case R.id.settings_title_use_biometric_api:
123+
return tr("使用 Biometric Api", "使用 Biometric Api", "Use Biometric Api");
120124
case R.id.settings_sub_title_switch_alipay:
121125
return tr("启用支付宝指纹支付", "啟用支付宝指紋支付", "Enable fingerprint payment for Alipay");
122126
case R.id.settings_sub_title_switch_wechat:
@@ -137,8 +141,12 @@ public static String getString(int res) {
137141
return tr("请输入云闪付的支付密码, 密码会加密后保存, 请放心", "請輸入雲閃付的支付密碼, 密碼會加密后保存, 請放心", "Please enter your Payment password");
138142
case R.id.settings_sub_title_donate:
139143
return tr("如果您觉得本软件好用, 欢迎赞助, 多少都是心意", "如果您覺得本軟件好用, 歡迎贊助, 多少都是心意", "Donate me, If you like this project");
144+
case R.id.settings_sub_title_advance:
145+
return tr("指纹图标、Biometric Api...", "指紋圖標、Biometric Api...", "Fingerprint icon, Biometric API...");
140146
case R.id.settings_sub_title_update_modules_same_time:
141147
return tr("将同时升级以下模块", "將同時升級以下模塊", "The following modules will be upgraded at the same time");
148+
case R.id.settings_sub_title_use_biometric_api:
149+
return tr("实验性, 仅 Android 9+ 可用", "實驗性, 僅 Android 9+ 可用", "Experimental, available only on Android 9+");
142150
case R.id.fingerprint_verification:
143151
return tr("请验证指纹", "請驗證指紋", "Fingerprint verification");
144152
case R.id.wechat_general:
@@ -198,6 +206,8 @@ public static String getString(int res) {
198206
return tr("支付密码加密成功", "支付密碼加密成功", "Payment password encryption successful");
199207
case R.id.toast_fingerprint_password_dec_failed:
200208
return tr("支付密码解密失败, 请重新设定支付密码", "支付密码解密失败, 请重新设定支付密码", "Decryption of payment password failed, please reset the payment password");
209+
case R.id.toast_fingerprint_operation_cancel:
210+
return tr("操作已取消", "操作已取消", "The operation has been canceled");
201211
case R.id.toast_password_not_set_alipay:
202212
return tr("未设定支付密码,请前往設置->指紋設置中设定支付宝的支付密码", "未設定支付密碼,請前往設置 -> 指紋設置中設定支付寶的支付密碼", "Payment password not set, please goto Settings -> Fingerprint to enter you payment password");
203213
case R.id.toast_password_not_set_taobao:
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.surcumference.fingerprint.listener;
22

3-
import android.view.View;
4-
53
/**
64
* Created by Jason on 2022/3/31.
75
*/
86

9-
public interface OnShowListener {
7+
public interface OnShowListener<T> {
108

11-
void onShow(View v);
9+
void onShow(T target);
1210
}

app/src/main/java/com/surcumference/fingerprint/plugin/impl/alipay/AlipayBasePlugin.java

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import com.surcumference.fingerprint.util.drawable.XDrawable;
4343
import com.surcumference.fingerprint.util.log.L;
4444
import com.surcumference.fingerprint.view.AlipayPayView;
45-
import com.surcumference.fingerprint.view.DialogFrameLayout;
4645
import com.surcumference.fingerprint.view.SettingsView;
4746
import com.wei.android.lib.fingerprintidentify.bean.FingerprintIdentifyFailInfo;
4847

@@ -103,7 +102,32 @@ public void onActivityCreated(Activity activity) {
103102
Task.onMain(100, () -> doSettingsMenuInject_10_1_38(activity));
104103
} else if (activityClzName.contains(".UserSettingActivity")) {
105104
Task.onMain(100, () -> doSettingsMenuInject(activity));
106-
} else if (activityClzName.contains(".PayPwdDialogActivity")
105+
}
106+
} catch (Exception e) {
107+
L.e(e);
108+
}
109+
}
110+
111+
@Override
112+
public void onActivityPaused(Activity activity) {
113+
114+
}
115+
116+
@Override
117+
public boolean getMockCurrentUser() {
118+
return false;
119+
}
120+
121+
122+
public void onActivityResumed(Activity activity) {
123+
try {
124+
final String activityClzName = activity.getClass().getName();
125+
if (BuildConfig.DEBUG) {
126+
L.d("activity", activity, "clz", activityClzName);
127+
}
128+
mCurrentActivity = activity;
129+
int versionCode = getVersionCode(activity);
130+
if (activityClzName.contains(".PayPwdDialogActivity")
107131
|| activityClzName.contains(".MspContainerActivity")
108132
|| activityClzName.contains(".FlyBirdWindowActivity")) {
109133
L.d("found");
@@ -124,7 +148,7 @@ public void onActivityCreated(Activity activity) {
124148
if (mCurrentActivity != activity) {
125149
return;
126150
}
127-
if (alipayVersionCode >= 661 /** 10.3.10.8310 */) {
151+
if (versionCode >= 661 /** 10.3.10.8310 */) {
128152
if (ViewUtils.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "simplePwdLayout") == null
129153
&& ViewUtils.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "mini_linSimplePwdComponent") == null
130154
&& ViewUtils.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "input_et_password") == null) {
@@ -138,7 +162,7 @@ public void onActivityCreated(Activity activity) {
138162
}
139163
return;
140164
}
141-
if (ViewUtils.findViewByName(activity, (alipayVersionCode >= 352 /** 10.2.13.7000 */ ? "com.alipay.android.safepaysdk" : "com.alipay.android.app"), "simplePwdLayout") == null
165+
if (ViewUtils.findViewByName(activity, (versionCode >= 352 /** 10.2.13.7000 */ ? "com.alipay.android.safepaysdk" : "com.alipay.android.app"), "simplePwdLayout") == null
142166
&& ViewUtils.findViewByName(activity, "com.alipay.android.phone.safepaybase", "mini_linSimplePwdComponent") == null
143167
&& ViewUtils.findViewByName(activity, "com.alipay.android.phone.safepaysdk", "mini_linSimplePwdComponent") == null
144168
&& ViewUtils.findViewByName(activity, "com.alipay.android.phone.mobilecommon.verifyidentity", "input_et_password") == null ) {
@@ -158,7 +182,6 @@ public void onActivityCreated(Activity activity) {
158182
}
159183
activity.getWindow().getDecorView().setAlpha(0);
160184
Task.onMain(1500, () -> {
161-
int versionCode = getVersionCode(activity);
162185
DigitPasswordKeyPadInfo digitPasswordKeyPad = AlipayVersionControl.getDigitPasswordKeyPad(versionCode);
163186
View key1View = ViewUtils.findViewByName(activity, digitPasswordKeyPad.modulePackageName, digitPasswordKeyPad.key1);
164187
if (key1View != null) {
@@ -175,36 +198,32 @@ public void onActivityCreated(Activity activity) {
175198
}
176199
}
177200

178-
@Override
179-
public void onActivityPaused(Activity activity) {
180-
181-
}
182-
183-
@Override
184-
public boolean getMockCurrentUser() {
185-
return false;
186-
}
187-
188-
189-
public void onActivityResumed(Activity activity) {
190-
L.d("activity resumed", activity);
191-
mCurrentActivity = activity;
192-
}
193-
194-
public void initFingerPrintLock(final Context context, OnFingerprintVerificationOKListener onSuccessUnlockCallback) {
201+
public void initFingerPrintLock(final Context context, AlertDialog dialog,
202+
OnFingerprintVerificationOKListener onSuccessUnlockCallback) {
195203
mFingerprintIdentify = new XFingerprintIdentify(context)
196204
.startIdentify(new XFingerprintIdentify.IdentifyListener() {
205+
206+
@Override
207+
public void onInited(XFingerprintIdentify identify) {
208+
super.onInited(identify);
209+
if (identify.isUsingBiometricApi()) {
210+
ViewUtils.setAlpha(dialog, 0);
211+
ViewUtils.setDimAmount(dialog, 0);
212+
}
213+
}
214+
197215
@Override
198-
public void onSucceed(Cipher cipher) {
199-
super.onSucceed(cipher);
216+
public void onSucceed(XFingerprintIdentify target, Cipher cipher) {
217+
super.onSucceed(target, cipher);
200218
onSuccessUnlockCallback.onFingerprintVerificationOK(cipher);
201219
}
202220

203221
@Override
204-
public void onFailed(FingerprintIdentifyFailInfo failInfo) {
205-
super.onFailed(failInfo);
206-
AlertDialog dialog = mFingerPrintAlertDialog;
222+
public void onFailed(XFingerprintIdentify target, FingerprintIdentifyFailInfo failInfo) {
223+
super.onFailed(target, failInfo);
207224
if (dialog != null) {
225+
ViewUtils.setAlpha(dialog, 1);
226+
ViewUtils.setDimAmount(dialog, 0.6f);
208227
if (dialog.isShowing()) {
209228
dialog.dismiss();
210229
}
@@ -215,6 +234,7 @@ public void onFailed(FingerprintIdentifyFailInfo failInfo) {
215234

216235
public boolean showFingerPrintDialog(final Activity activity) {
217236
final Context context = activity;
237+
final Config config = Config.from(context);
218238
try {
219239
if (getVersionCode(activity) >= 224) {
220240
if (activity.getClass().getName().contains(".MspContainerActivity")) {
@@ -227,61 +247,64 @@ public boolean showFingerPrintDialog(final Activity activity) {
227247
}
228248

229249
hidePreviousPayDialog();
250+
String passwordEncrypted = config.getPasswordEncrypted();
251+
if (TextUtils.isEmpty(passwordEncrypted) || TextUtils.isEmpty(config.getPasswordIV())) {
252+
Toaster.showLong(Lang.getString(R.id.toast_password_not_set_alipay));
253+
return true;
254+
}
255+
230256
activity.getWindow().getDecorView().setAlpha(0);
231257
mPwdActivityDontShowFlag = false;
232258
mPwdActivityReShowDelayTimeMsec = 0;
233259
clickDigitPasswordWidget(activity);
234-
initFingerPrintLock(context, (cipher) -> {
235-
BlackListUtils.applyIfNeeded(context);
236-
String passwordEncrypted = Config.from(activity).getPasswordEncrypted();
237-
if (TextUtils.isEmpty(passwordEncrypted)) {
238-
Toaster.showShort(Lang.getString(R.id.toast_password_not_set_alipay));
239-
return;
240-
}
241-
String password = AESUtils.decrypt(cipher, passwordEncrypted);
242-
if (TextUtils.isEmpty(password)) {
243-
Toaster.showShort(Lang.getString(R.id.toast_fingerprint_password_dec_failed));
244-
return;
245-
}
260+
AlipayPayView alipayPayView = new AlipayPayView(context)
261+
.withOnShowListener((target) -> {
262+
initFingerPrintLock(context, target.getDialog(), (cipher) -> {
263+
BlackListUtils.applyIfNeeded(context);
264+
String password = AESUtils.decrypt(cipher, passwordEncrypted);
265+
if (TextUtils.isEmpty(password)) {
266+
Toaster.showShort(Lang.getString(R.id.toast_fingerprint_password_dec_failed));
267+
return;
268+
}
246269

247-
Runnable onCompleteRunnable = () -> {
248-
mPwdActivityReShowDelayTimeMsec = 1000;
249-
AlertDialog dialog = mFingerPrintAlertDialog;
250-
if (dialog != null) {
251-
dialog.dismiss();
252-
}
253-
};
254-
255-
if (!tryInputGenericPassword(activity, password)) {
256-
boolean tryAgain = false;
257-
try {
258-
inputDigitPassword(activity, password);
259-
} catch (NullPointerException e) {
260-
tryAgain = true;
261-
} catch (Exception e) {
262-
Toaster.showLong(Lang.getString(R.id.toast_password_auto_enter_fail));
263-
L.e(e);
264-
}
265-
if (tryAgain) {
266-
clickDigitPasswordWidget(activity);
267-
Task.onMain(1000, ()-> {
270+
Runnable onCompleteRunnable = () -> {
271+
mPwdActivityReShowDelayTimeMsec = 1000;
272+
AlertDialog dialog = mFingerPrintAlertDialog;
273+
if (dialog != null) {
274+
dialog.dismiss();
275+
}
276+
};
277+
278+
if (!tryInputGenericPassword(activity, password)) {
279+
boolean tryAgain = false;
268280
try {
269281
inputDigitPassword(activity, password);
270282
} catch (NullPointerException e) {
271-
Toaster.showLong(Lang.getString(R.id.toast_password_auto_enter_fail));
272-
L.d("inputDigitPassword NPE", e);
283+
tryAgain = true;
273284
} catch (Exception e) {
274285
Toaster.showLong(Lang.getString(R.id.toast_password_auto_enter_fail));
275286
L.e(e);
276287
}
277-
onCompleteRunnable.run();
278-
});
279-
return;
280-
}
281-
}
282-
onCompleteRunnable.run();
283-
});
284-
DialogFrameLayout alipayPayView = new AlipayPayView(context).withOnCloseImageClickListener((target, v) -> {
288+
if (tryAgain) {
289+
clickDigitPasswordWidget(activity);
290+
Task.onMain(1000, ()-> {
291+
try {
292+
inputDigitPassword(activity, password);
293+
} catch (NullPointerException e) {
294+
Toaster.showLong(Lang.getString(R.id.toast_password_auto_enter_fail));
295+
L.d("inputDigitPassword NPE", e);
296+
} catch (Exception e) {
297+
Toaster.showLong(Lang.getString(R.id.toast_password_auto_enter_fail));
298+
L.e(e);
299+
}
300+
onCompleteRunnable.run();
301+
});
302+
return;
303+
}
304+
}
305+
onCompleteRunnable.run();
306+
});
307+
}).withOnCloseImageClickListener((target, v) -> {
285308
mPwdActivityDontShowFlag = true;
286309
target.getDialog().dismiss();
287310
activity.onBackPressed();

0 commit comments

Comments
 (0)