Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Unified Diff: ios/chrome/browser/payments/payment_request_manager.mm

Issue 2701923003: [Payment Request] Error message screen (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/payments/payment_request_manager.mm
diff --git a/ios/chrome/browser/payments/payment_request_manager.mm b/ios/chrome/browser/payments/payment_request_manager.mm
index 5bab9194d65f113d863ccfc166c7dc50593dbf85..aed2a47915a4309bd0f2318aad67d8b2f1af41f6 100644
--- a/ios/chrome/browser/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/payments/payment_request_manager.mm
@@ -4,6 +4,7 @@
#import "ios/chrome/browser/payments/payment_request_manager.h"
+#include "base/ios/block_types.h"
#include "base/ios/ios_util.h"
#import "base/mac/bind_objc_block.h"
#include "base/mac/foundation_util.h"
@@ -67,9 +68,6 @@ const NSTimeInterval kTimeoutInterval = 60.0;
// Observer for |_webState|.
std::unique_ptr<web::WebStateObserverBridge> _webStateObserver;
- // Object that manages JavaScript injection into the web view.
- __weak JSPaymentRequestManager* _paymentRequestJsManager;
-
// Boolean to track if the current WebState is enabled (JS callback is set
// up).
BOOL _webStateEnabled;
@@ -88,11 +86,18 @@ const NSTimeInterval kTimeoutInterval = 60.0;
// Timer used to periodically unblock the webview's JS event queue.
NSTimer* _unblockEventQueueTimer;
- // Timer used to close the UI if the page does not call
- // PaymentResponse.complete() in a timely fashion.
+ // Timer used to complete the Payment Request flow and close the UI if the
+ // page does not call PaymentResponse.complete() in a timely fashion.
NSTimer* _paymentResponseTimeoutTimer;
+
+ // Timer used to cancel the Payment Request flow and close the UI if the
+ // page does not settle the pending update promise in a timely fashion.
+ NSTimer* _updateEventTimeoutTimer;
}
+// Object that manages JavaScript injection into the web view.
+@property(nonatomic, weak) JSPaymentRequestManager* paymentRequestJsManager;
+
// Synchronous method executed by -asynchronouslyEnablePaymentRequest:
- (void)doEnablePaymentRequest:(BOOL)enabled;
@@ -107,9 +112,14 @@ const NSTimeInterval kTimeoutInterval = 60.0;
// invocation was successful.
- (BOOL)handleRequestShow:(const base::DictionaryValue&)message;
+// Called by |_paymentResponseTimeoutTimer|, invokes handleResponseComplete:
+// as if PaymentResponse.complete() was invoked with the default "unknown"
+// argument.
+- (BOOL)handleResponseComplete;
+
// Handles invocations of PaymentResponse.complete(). Returns YES if the
// invocation was successful.
-- (BOOL)handleResponseComplete;
+- (BOOL)handleResponseComplete:(const base::DictionaryValue&)message;
// Handles invocations of PaymentRequestUpdateEvent.updateWith(). Returns YES if
// the invocation was successful.
@@ -126,6 +136,13 @@ const NSTimeInterval kTimeoutInterval = 60.0;
// called with no arguments.
- (void)setPaymentResponseTimeoutTimer;
+// Establishes a timer that dismisses the Payment Request UI when it times out.
+// Per the spec, implementations may choose to consider a timeout for the
+// promise provided with the PaymentRequestUpdateEvent.updateWith() call. If the
+// promise doesn't get settled in a reasonable amount of time, it is as if it
+// was rejected.
+- (void)setUpdateEventTimeoutTimer;
+
@end
@implementation PaymentRequestManager
@@ -133,6 +150,7 @@ const NSTimeInterval kTimeoutInterval = 60.0;
@synthesize enabled = _enabled;
@synthesize webState = _webState;
@synthesize browserState = _browserState;
+@synthesize paymentRequestJsManager = _paymentRequestJsManager;
- (instancetype)initWithBaseViewController:(UIViewController*)viewController
browserState:
@@ -275,7 +293,7 @@ const NSTimeInterval kTimeoutInterval = 60.0;
return [self handleRequestCancel];
}
if (command == "paymentRequest.responseComplete") {
- return [self handleResponseComplete];
+ return [self handleResponseComplete:JSONCommand];
}
if (command == "paymentRequest.updatePaymentDetails") {
return [self handleUpdatePaymentDetails:JSONCommand];
@@ -334,22 +352,58 @@ const NSTimeInterval kTimeoutInterval = 60.0;
[_unblockEventQueueTimer invalidate];
[_paymentResponseTimeoutTimer invalidate];
+ [_updateEventTimeoutTimer invalidate];
+
+ __weak PaymentRequestManager* weakSelf = self;
+ ProceduralBlock callback = ^{
+ PaymentRequestManager* strongSelf = weakSelf;
+ // Early return if the manager has been deallocated.
+ if (!strongSelf)
+ return;
+ [strongSelf cancelRequestWithErrorMessage:@"Request canceled."];
+ };
- [self cancelRequestWithErrorMessage:@"Request canceled by the page."];
+ [_paymentRequestCoordinator displayErrorWithCallback:callback];
return YES;
}
- (BOOL)handleResponseComplete {
+ base::DictionaryValue command;
+ command.SetString("result", "unknown");
+ return [self handleResponseComplete:command];
+}
+
+- (BOOL)handleResponseComplete:(const base::DictionaryValue&)message {
// TODO(crbug.com/602666): Check that there *is* a pending response here.
- // TODO(crbug.com/602666): Indicate success or failure in the UI.
[_unblockEventQueueTimer invalidate];
[_paymentResponseTimeoutTimer invalidate];
+ [_updateEventTimeoutTimer invalidate];
- [self dismissUI];
+ std::string result;
+ if (!message.GetString("result", &result)) {
+ DLOG(ERROR) << "JS message parameter 'result' is missing";
+ return NO;
+ }
- [_paymentRequestJsManager resolveResponsePromiseWithCompletionHandler:nil];
+ __weak PaymentRequestManager* weakSelf = self;
+ ProceduralBlock callback = ^{
+ PaymentRequestManager* strongSelf = weakSelf;
+ // Early return if the manager has been deallocated.
+ if (!strongSelf)
+ return;
+ [strongSelf dismissUI];
+ [strongSelf.paymentRequestJsManager
+ resolveResponsePromiseWithCompletionHandler:nil];
+ };
+
+ // Display UI indicating failure if the value of |result| is "fail".
+ if (result == "fail") {
+ [_paymentRequestCoordinator displayErrorWithCallback:callback];
+ } else {
+ callback();
+ }
return YES;
}
@@ -358,6 +412,7 @@ const NSTimeInterval kTimeoutInterval = 60.0;
// TODO(crbug.com/602666): Check that there is already a pending request.
[_unblockEventQueueTimer invalidate];
+ [_updateEventTimeoutTimer invalidate];
const base::DictionaryValue* paymentDetailsData = nullptr;
web::PaymentDetails paymentDetails;
@@ -393,6 +448,15 @@ const NSTimeInterval kTimeoutInterval = 60.0;
repeats:NO];
}
+- (void)setUpdateEventTimeoutTimer {
+ _updateEventTimeoutTimer =
+ [NSTimer scheduledTimerWithTimeInterval:kTimeoutInterval
+ target:self
+ selector:@selector(handleRequestCancel)
+ userInfo:nil
+ repeats:NO];
+}
+
- (void)dismissUI {
[_paymentRequestCoordinator stop];
_paymentRequestCoordinator = nil;
@@ -419,7 +483,7 @@ const NSTimeInterval kTimeoutInterval = 60.0;
- (void)paymentRequestCoordinatorDidCancel:
(PaymentRequestCoordinator*)coordinator {
- [self cancelRequestWithErrorMessage:@"Request canceled by user."];
+ [self cancelRequestWithErrorMessage:@"Request canceled."];
}
- (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
@@ -436,6 +500,7 @@ const NSTimeInterval kTimeoutInterval = 60.0;
[_paymentRequestJsManager updateShippingAddress:shippingAddress
completionHandler:nil];
[self setUnblockEventQueueTimer];
+ [self setUpdateEventTimeoutTimer];
}
- (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
@@ -443,6 +508,7 @@ const NSTimeInterval kTimeoutInterval = 60.0;
[_paymentRequestJsManager updateShippingOption:shippingOption
completionHandler:nil];
[self setUnblockEventQueueTimer];
+ [self setUpdateEventTimeoutTimer];
}
#pragma mark - CRWWebStateObserver methods

Powered by Google App Engine
This is Rietveld 408576698