44
55import android .app .Activity ;
66import android .app .AlertDialog ;
7- import android .app .Instrumentation ;
87import android .content .Context ;
98import android .content .res .ColorStateList ;
109import android .graphics .Color ;
1110import android .graphics .Rect ;
11+ import android .os .Build ;
1212import android .os .Bundle ;
1313import android .text .TextUtils ;
1414import android .util .TypedValue ;
1515import android .view .Gravity ;
16- import android .view .KeyEvent ;
1716import android .view .View ;
1817import android .view .ViewGroup ;
18+ import android .view .ViewTreeObserver ;
1919import android .widget .AbsListView ;
2020import android .widget .FrameLayout ;
2121import android .widget .LinearLayout ;
3434import com .surcumference .fingerprint .plugin .inf .IMockCurrentUser ;
3535import com .surcumference .fingerprint .plugin .inf .OnFingerprintVerificationOKListener ;
3636import com .surcumference .fingerprint .util .ActivityViewObserver ;
37+ import com .surcumference .fingerprint .util .ActivityViewObserverHolder ;
3738import com .surcumference .fingerprint .util .ApplicationUtils ;
3839import com .surcumference .fingerprint .util .BizBiometricIdentify ;
3940import com .surcumference .fingerprint .util .BlackListUtils ;
5455public 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 ();
0 commit comments