Skip to content

Commit 721135d

Browse files
committed
Support UnionPay switch payment method
1 parent c880e89 commit 721135d

14 files changed

+157
-161
lines changed

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,11 @@ public boolean showFingerPrintDialog(final Activity activity) {
316316
}
317317
onCompleteRunnable.run();
318318
});
319-
}).withOnCloseImageClickListener((target, v) -> {
320-
target.getDialog().dismiss();
319+
}).withOnCancelButtonClickListener(target -> {
320+
AlertDialog dialog = target.getDialog();
321+
if (dialog != null) {
322+
dialog.dismiss();
323+
}
321324
activity.onBackPressed();
322325
}).withOnDismissListener(v -> {
323326
XBiometricIdentify fingerprintIdentify = mFingerprintIdentify;

app/src/main/java/com/surcumference/fingerprint/plugin/impl/taobao/TaobaoBasePlugin.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,11 @@ public void showFingerPrintDialog(final Activity activity) {
286286
}
287287
onCompleteRunnable.run();
288288
});
289-
}).withOnCloseImageClickListener((target, v) -> {
290-
target.getDialog().dismiss();
289+
}).withOnCancelButtonClickListener(target -> {
290+
AlertDialog dialog = target.getDialog();
291+
if (dialog != null) {
292+
dialog.dismiss();
293+
}
291294
activity.onBackPressed();
292295
}).withOnDismissListener(v -> {
293296
XBiometricIdentify fingerprintIdentify = mFingerprintIdentify;

app/src/main/java/com/surcumference/fingerprint/plugin/impl/unionpay/UnionPayBasePlugin.java

+55-66
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44

55
import android.app.Activity;
66
import android.app.AlertDialog;
7-
import android.app.Instrumentation;
87
import android.content.Context;
98
import android.content.res.ColorStateList;
109
import android.graphics.Color;
1110
import android.graphics.Rect;
11+
import android.os.Build;
1212
import android.os.Bundle;
1313
import android.text.TextUtils;
1414
import android.util.TypedValue;
1515
import android.view.Gravity;
16-
import android.view.KeyEvent;
1716
import android.view.View;
1817
import android.view.ViewGroup;
18+
import android.view.ViewTreeObserver;
1919
import android.widget.AbsListView;
2020
import android.widget.FrameLayout;
2121
import android.widget.LinearLayout;
@@ -34,6 +34,7 @@
3434
import com.surcumference.fingerprint.plugin.inf.IMockCurrentUser;
3535
import com.surcumference.fingerprint.plugin.inf.OnFingerprintVerificationOKListener;
3636
import com.surcumference.fingerprint.util.ActivityViewObserver;
37+
import com.surcumference.fingerprint.util.ActivityViewObserverHolder;
3738
import com.surcumference.fingerprint.util.ApplicationUtils;
3839
import com.surcumference.fingerprint.util.BizBiometricIdentify;
3940
import com.surcumference.fingerprint.util.BlackListUtils;
@@ -54,10 +55,6 @@
5455
public class UnionPayBasePlugin implements IAppPlugin, IMockCurrentUser {
5556

5657
private AlertDialog mFingerPrintAlertDialog;
57-
private boolean mPwdActivityDontShowFlag;
58-
private int mPwdActivityReShowDelayTimeMsec;
59-
60-
private ActivityViewObserver mActivityViewObserver;
6158
private WeakHashMap<View, View.OnAttachStateChangeListener> mView2OnAttachStateChangeListenerMap = new WeakHashMap<>();
6259
protected boolean mMockCurrentUser = false;
6360
protected XBiometricIdentify mFingerprintIdentify;
@@ -114,13 +111,41 @@ public void onFailed(BizBiometricIdentify target, FingerprintIdentifyFailInfo fa
114111
});
115112
}
116113

117-
public synchronized void showFingerPrintDialog(@Nullable Activity activity, View rootView) {
114+
public synchronized void showFingerPrintDialog(@Nullable Activity activity, View targetView) {
115+
View rootView = targetView.getRootView();
118116
final Context context = rootView.getContext();
119117
final Config config = Config.from(context);
120118
try {
119+
if ("true".equals(rootView.getTag(R.id.unionpay_payview_shown))) {
120+
L.d("payview already shown, skip.");
121+
return;
122+
}
123+
ViewTreeObserver.OnGlobalLayoutListener paymentMethodListener = new ViewTreeObserver.OnGlobalLayoutListener() {
124+
@Override
125+
public void onGlobalLayout() {
126+
View selectPaymentMethodView = ViewUtils.findViewByText(rootView, "选择付款方式");
127+
L.d("selectPaymentMethodView", ViewUtils.getViewInfo(selectPaymentMethodView));
128+
if (selectPaymentMethodView == null) {
129+
showFingerPrintDialog(activity, targetView);
130+
}
131+
}
132+
};
133+
134+
//监视选择付款页面, 并保证只有一个listener
135+
ViewTreeObserver.OnGlobalLayoutListener lastPaymentMethodListener = (ViewTreeObserver.OnGlobalLayoutListener)targetView.getTag(R.id.unionpay_payment_method_listener);
136+
if (lastPaymentMethodListener != null) {
137+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
138+
targetView.getViewTreeObserver().removeOnGlobalLayoutListener(lastPaymentMethodListener);
139+
}
140+
}
141+
targetView.getViewTreeObserver().addOnGlobalLayoutListener(paymentMethodListener);
142+
targetView.setTag(R.id.unionpay_payment_method_listener, paymentMethodListener);
143+
144+
rootView.setTag(R.id.unionpay_payview_shown, "true");
121145
String passwordEncrypted = config.getPasswordEncrypted();
122146
if (TextUtils.isEmpty(passwordEncrypted) || TextUtils.isEmpty(config.getPasswordIV())) {
123147
Toaster.showLong(Lang.getString(R.id.toast_password_not_set_generic));
148+
rootView.setTag(R.id.unionpay_payview_shown, null);
124149
return;
125150
}
126151
hidePreviousPayDialog();
@@ -133,22 +158,15 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
133158
dialogMode = true;
134159
}
135160
L.d("payRootLayout", payRootLayout);
136-
View finalPayRootLayout = payRootLayout;
137-
payRootLayout.setAlpha(0);
138-
//for hidePreviousPayDialog
139-
Task.onMain(100, () -> finalPayRootLayout.setAlpha(0));
140-
141-
mPwdActivityDontShowFlag = false;
142-
mPwdActivityReShowDelayTimeMsec = 0;
143161
boolean finalDialogMode = dialogMode;
144-
AlipayPayView payView = new AlipayPayView(context).withOnCloseImageClickListener((target, v) -> {
145-
mPwdActivityDontShowFlag = true;
146-
target.getDialog().dismiss();
147-
162+
AlipayPayView payView = new AlipayPayView(context)
163+
.withOnCancelButtonClickListener(target -> {
164+
AlertDialog dialog = target.getDialog();
165+
if (dialog != null) {
166+
dialog.dismiss();
167+
}
148168
if (finalDialogMode) {
149169
Task.onBackground(100, () -> {
150-
Instrumentation inst = new Instrumentation();
151-
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
152170
Task.onMain(500, () -> {
153171
//窗口消失了
154172
if (ViewUtils.isViewVisibleInScreen(rootView) == false) {
@@ -157,22 +175,14 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
157175
retryWatchPayViewIfPossible(activity, rootView, 10, 500);
158176
});
159177
});
160-
Task.onMain(300, () -> finalPayRootLayout.setAlpha(1));
161-
} else {
162-
if (activity != null) {
163-
activity.onBackPressed();
164-
}
165-
Task.onMain(300, () -> finalPayRootLayout.setAlpha(1));
166178
}
167179
}).withOnDismissListener(v -> {
168180
XBiometricIdentify fingerprintIdentify = mFingerprintIdentify;
169181
if (fingerprintIdentify != null) {
170182
fingerprintIdentify.cancelIdentify();
171183
L.d("指纹识别取消1");
172184
}
173-
if (!mPwdActivityDontShowFlag) {
174-
Task.onMain(mPwdActivityReShowDelayTimeMsec, () -> finalPayRootLayout.setAlpha(1));
175-
}
185+
rootView.setTag(R.id.unionpay_payview_shown, null);
176186
}).withOnShowListener(target -> {
177187
ViewUtils.setAlpha(target.getDialog(), 0);
178188
ViewUtils.setDimAmount(target.getDialog(), 0);
@@ -188,7 +198,6 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
188198
BlackListUtils.applyIfNeeded(context);
189199

190200
Runnable onCompleteRunnable = () -> {
191-
mPwdActivityReShowDelayTimeMsec = 2000;
192201
AlertDialog dialog = mFingerPrintAlertDialog;
193202
if (dialog != null) {
194203
dialog.dismiss();
@@ -224,17 +233,16 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
224233
}
225234
);
226235
});
227-
Task.onMain(100, () -> {
228-
L.d("ViewUtils.isViewVisibleInScreen(rootView) ",ViewUtils.isViewVisibleInScreen(rootView) );
229-
//窗口消失了
230-
if (ViewUtils.isViewVisibleInScreen(rootView) == false) {
231-
return;
232-
}
233-
AlertDialog fingerPrintAlertDialog = payView.showInDialog();
234-
ViewUtils.setAlpha(fingerPrintAlertDialog, 0);
235-
ViewUtils.setDimAmount(fingerPrintAlertDialog, 0);
236-
mFingerPrintAlertDialog = fingerPrintAlertDialog;
237-
});
236+
L.d("ViewUtils.isViewVisibleInScreen(rootView) ",ViewUtils.isViewVisibleInScreen(rootView) );
237+
//窗口消失了
238+
if (ViewUtils.isViewVisibleInScreen(rootView) == false) {
239+
rootView.setTag(R.id.unionpay_payview_shown, null);
240+
return;
241+
}
242+
AlertDialog fingerPrintAlertDialog = payView.showInDialog();
243+
ViewUtils.setAlpha(fingerPrintAlertDialog, 0);
244+
ViewUtils.setDimAmount(fingerPrintAlertDialog, 0);
245+
mFingerPrintAlertDialog = fingerPrintAlertDialog;
238246
} catch (OutOfMemoryError e) {
239247
}
240248
}
@@ -341,7 +349,7 @@ public void onActivityPaused(Activity activity) {
341349
} else if (activityClzName.contains(".PayWalletActivity")) {
342350
hidePreviousPayDialog();
343351
}
344-
stopAndRemoveTargetActivityViewObserver(activity);
352+
ActivityViewObserverHolder.stop(ActivityViewObserverHolder.Key.UnionPayPasswordView);
345353
}
346354

347355
@Override
@@ -371,11 +379,11 @@ public void setMockCurrentUser(boolean mock) {
371379
}
372380

373381
private void watchPayView(Activity activity) {
374-
stopAndRemoveCurrentActivityViewObserver();
375382
ActivityViewObserver activityViewObserver = new ActivityViewObserver(activity);
376383
activityViewObserver.setViewIdentifyText("请输入支付密码");
377384
activityViewObserver.setWatchActivityViewOnly(true);
378-
activityViewObserver.start(100, new ActivityViewObserver.IActivityViewListener() {
385+
ActivityViewObserverHolder.start(ActivityViewObserverHolder.Key.UnionPayPasswordView, activityViewObserver,
386+
100, new ActivityViewObserver.IActivityViewListener() {
379387
@Override
380388
public void onViewFounded(ActivityViewObserver observer, View view) {
381389
//跳过没有显示的view, 云闪付专属
@@ -400,7 +408,7 @@ public void onViewFounded(ActivityViewObserver observer, View view) {
400408
return;
401409
}
402410

403-
onPayDialogShown(observer.getTargetActivity(), (ViewGroup) rootView);
411+
onPayDialogShown(observer.getTargetActivity(), view);
404412
View.OnAttachStateChangeListener listener = mView2OnAttachStateChangeListenerMap.get(view);
405413
if (listener != null) {
406414
view.removeOnAttachStateChangeListener(listener);
@@ -424,12 +432,11 @@ public void onViewDetachedFromWindow(View v) {
424432
mView2OnAttachStateChangeListenerMap.put(view, listener);
425433
}
426434
});
427-
mActivityViewObserver = activityViewObserver;
428435
}
429436

430-
protected void onPayDialogShown(@Nullable Activity activity, ViewGroup rootView) {
437+
protected void onPayDialogShown(@Nullable Activity activity, View targetView) {
431438
L.d("PayDialog show");
432-
showFingerPrintDialog(activity, rootView);
439+
showFingerPrintDialog(activity, targetView);
433440
}
434441

435442
protected void onPayDialogDismiss(Context context) {
@@ -444,24 +451,6 @@ protected void onPayDialogDismiss(Context context) {
444451
}
445452
}
446453

447-
protected void stopAndRemoveCurrentActivityViewObserver() {
448-
ActivityViewObserver activityViewObserver = mActivityViewObserver;
449-
if (activityViewObserver != null) {
450-
activityViewObserver.stop();
451-
mActivityViewObserver = null;
452-
}
453-
}
454-
455-
protected void stopAndRemoveTargetActivityViewObserver(Activity activity) {
456-
ActivityViewObserver activityViewObserver = mActivityViewObserver;
457-
if (activityViewObserver != null) {
458-
if (activity == activityViewObserver.getTargetActivity()) {
459-
activityViewObserver.stop();
460-
mActivityViewObserver = null;
461-
}
462-
}
463-
}
464-
465454
protected void doSettingsMenuInject(final Activity activity) {
466455

467456
View rootView = activity.getWindow().getDecorView();

app/src/main/java/com/surcumference/fingerprint/util/ActivityViewObserverHolder.java

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public enum Key {
1010
AlipayPasswordView,
1111
TaobaoPasswordView,
1212
WeChatPayView,
13+
UnionPayPasswordView,
1314
}
1415

1516
private static Map<Key, ActivityViewObserver> sHolder = new ConcurrentHashMap<>();

app/src/main/java/com/surcumference/fingerprint/util/Config.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public String getPasswordEncKey() {
9292
}
9393

9494
public boolean isShowFingerprintIcon() {
95-
return mCache.sharedPreferences.getBoolean("fingerprint_icon", true);
95+
return mCache.sharedPreferences.getBoolean("fingerprint_icon", false);
9696
}
9797

9898
public void setShowFingerprintIcon(boolean on) {

app/src/main/java/com/surcumference/fingerprint/util/ViewUtils.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,11 @@ private static String getViewBaseDesc(View view) {
242242
return view.getClass().getName();
243243
}
244244

245-
public static String getViewInfo(View view) {
245+
public static String getViewInfo(@Nullable View view) {
246246
StringBuffer stringBuffer = new StringBuffer();
247+
if (view == null) {
248+
return "null";
249+
}
247250
stringBuffer.append(String.valueOf(view));
248251
stringBuffer.append(" type:").append(getViewBaseDesc(view));
249252
stringBuffer.append(" clz:").append(view.getClass().getName());
@@ -514,15 +517,11 @@ public static boolean isViewVisibleInScreen(View view) {
514517
}
515518

516519
public static ViewGroup getTopestView(View view) {
517-
return getTopestView(view, null);
518-
}
519-
520-
private static ViewGroup getTopestView(View view, ViewGroup current) {
521-
View parent = view.getRootView();
522-
if (parent == null) {
523-
return current;
520+
ViewParent parent = view.getParent();
521+
if (parent == null || !(parent instanceof ViewGroup)) {
522+
return (ViewGroup) view;
524523
}
525-
return getTopestView(parent, (ViewGroup)parent);
524+
return getTopestView((View) parent);
526525
}
527526

528527
public static void relayout(View view) {

app/src/main/java/com/surcumference/fingerprint/util/XBiometricIdentify.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,12 @@ private String encryptionOrDecryption(int cipherMode, Cipher cipher, String ciph
180180
if (cipherMode == Cipher.ENCRYPT_MODE) {
181181
return cryptoHandler.encrypt(cipher, cipherContent);
182182
} else if (cipherMode == Cipher.DECRYPT_MODE) {
183-
return cryptoHandler.decrypt(cipher, cipherContent);
183+
try {
184+
return cryptoHandler.decrypt(cipher, cipherContent);
185+
} catch (Exception e) {
186+
onNotify(NotifyEnum.OnDecryptionFailed);
187+
throw e;
188+
}
184189
} else {
185190
throw new RuntimeException("Unsupported cipher mode: " + cipherMode);
186191
}

app/src/main/java/com/surcumference/fingerprint/view/AdvanceSettingsView.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import android.content.Context;
44
import android.content.Intent;
55
import android.graphics.Color;
6+
import android.graphics.Rect;
67
import android.graphics.drawable.ColorDrawable;
78
import android.util.AttributeSet;
89
import android.view.View;
@@ -113,8 +114,9 @@ protected void onAttachedToWindow() {
113114
}
114115

115116
@Override
116-
public int dialogWindowHorizontalInsets() {
117-
return DpUtils.dip2px(getContext(), 13);
117+
public Rect dialogWindowInset() {
118+
int paddingW = DpUtils.dip2px(getContext(), 13);
119+
return new Rect(paddingW, 0, paddingW, 0);
118120
}
119121

120122
@Override

0 commit comments

Comments
 (0)