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

Side by Side Diff: ios/chrome/browser/payments/payment_request_manager.mm

Issue 2632463003: Add a timeout if the page doesn't call complete() in a timely fashion. (Closed)
Patch Set: Fix comment. Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/payments/payment_request_manager.h" 5 #import "ios/chrome/browser/payments/payment_request_manager.h"
6 6
7 #include "base/ios/ios_util.h" 7 #include "base/ios/ios_util.h"
8 #import "base/ios/weak_nsobject.h" 8 #import "base/ios/weak_nsobject.h"
9 #import "base/mac/bind_objc_block.h" 9 #import "base/mac/bind_objc_block.h"
10 #include "base/mac/foundation_util.h" 10 #include "base/mac/foundation_util.h"
(...skipping 14 matching lines...) Expand all
25 #import "ios/web/public/url_scheme_util.h" 25 #import "ios/web/public/url_scheme_util.h"
26 #import "ios/web/public/web_state/crw_web_view_proxy.h" 26 #import "ios/web/public/web_state/crw_web_view_proxy.h"
27 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" 27 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
28 #include "ios/web/public/web_state/url_verification_constants.h" 28 #include "ios/web/public/web_state/url_verification_constants.h"
29 #include "ios/web/public/web_state/web_state.h" 29 #include "ios/web/public/web_state/web_state.h"
30 #import "ios/web/public/web_state/web_state_observer_bridge.h" 30 #import "ios/web/public/web_state/web_state_observer_bridge.h"
31 31
32 namespace { 32 namespace {
33 // Command prefix for injected JavaScript. 33 // Command prefix for injected JavaScript.
34 const std::string kCommandPrefix = "paymentRequest"; 34 const std::string kCommandPrefix = "paymentRequest";
35
36 // Time interval between attempts to unblock the webview's JS event queue.
37 const NSTimeInterval kNoopInterval = 0.1;
38
39 // Time interval before closing the UI if the page has not yet called
40 // PaymentResponse.complete().
41 const NSTimeInterval kTimeoutInterval = 60.0;
42
35 } // namespace 43 } // namespace
36 44
37 @interface PaymentRequestManager ()<CRWWebStateObserver, 45 @interface PaymentRequestManager ()<CRWWebStateObserver,
38 PaymentRequestCoordinatorDelegate> { 46 PaymentRequestCoordinatorDelegate> {
39 // View controller used to present the PaymentRequest view controller. 47 // View controller used to present the PaymentRequest view controller.
40 base::WeakNSObject<UIViewController> _baseViewController; 48 base::WeakNSObject<UIViewController> _baseViewController;
41 49
42 // PersonalDataManager used to manage user credit cards and addresses. 50 // PersonalDataManager used to manage user credit cards and addresses.
43 autofill::PersonalDataManager* _personalDataManager; 51 autofill::PersonalDataManager* _personalDataManager;
44 52
(...skipping 13 matching lines...) Expand all
58 // Boolean to track if the script has been injected in the current page. This 66 // Boolean to track if the script has been injected in the current page. This
59 // is a faster check than asking the JS controller. 67 // is a faster check than asking the JS controller.
60 BOOL _isScriptInjected; 68 BOOL _isScriptInjected;
61 69
62 // True when close has been called and the PaymentRequest coordinator has 70 // True when close has been called and the PaymentRequest coordinator has
63 // been destroyed. 71 // been destroyed.
64 BOOL _closed; 72 BOOL _closed;
65 73
66 // Coordinator used to create and present the PaymentRequest view controller. 74 // Coordinator used to create and present the PaymentRequest view controller.
67 base::scoped_nsobject<PaymentRequestCoordinator> _paymentRequestCoordinator; 75 base::scoped_nsobject<PaymentRequestCoordinator> _paymentRequestCoordinator;
76
77 // Timer used to periodically unblock the webview's JS event queue.
78 base::scoped_nsobject<NSTimer> _unblockEventQueueTimer;
79
80 // Timer used to close the UI if the page does not call
81 // PaymentResponse.complete() in a timely fashion.
82 base::scoped_nsobject<NSTimer> _paymentResponseTimeoutTimer;
68 } 83 }
69 84
70 // Synchronous method executed by -asynchronouslyEnablePaymentRequest: 85 // Synchronous method executed by -asynchronouslyEnablePaymentRequest:
71 - (void)doEnablePaymentRequest:(BOOL)enabled; 86 - (void)doEnablePaymentRequest:(BOOL)enabled;
72 87
73 // Initialize the PaymentRequest JavaScript. 88 // Initialize the PaymentRequest JavaScript.
74 - (void)initializeWebViewForPaymentRequest; 89 - (void)initializeWebViewForPaymentRequest;
75 90
76 // Handler for injected JavaScript callbacks. 91 // Handler for injected JavaScript callbacks.
77 - (BOOL)handleScriptCommand:(const base::DictionaryValue&)JSONCommand; 92 - (BOOL)handleScriptCommand:(const base::DictionaryValue&)JSONCommand;
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 282
268 [_paymentRequestCoordinator start]; 283 [_paymentRequestCoordinator start];
269 284
270 return YES; 285 return YES;
271 } 286 }
272 287
273 - (BOOL)handleResponseComplete { 288 - (BOOL)handleResponseComplete {
274 // TODO(crbug.com/602666): Check that there *is* a pending response here. 289 // TODO(crbug.com/602666): Check that there *is* a pending response here.
275 // TODO(crbug.com/602666): Indicate success or failure in the UI. 290 // TODO(crbug.com/602666): Indicate success or failure in the UI.
276 291
292 [_unblockEventQueueTimer invalidate];
293 [_paymentResponseTimeoutTimer invalidate];
294
277 [self dismissUI]; 295 [self dismissUI];
278 296
279 // TODO(crbug.com/602666): Reject the promise on failure.
280 [_paymentRequestJsManager resolveResponsePromise:nil]; 297 [_paymentRequestJsManager resolveResponsePromise:nil];
281 298
282 return YES; 299 return YES;
283 } 300 }
284 301
285 - (void)dismissUI { 302 - (void)dismissUI {
286 [_paymentRequestCoordinator stop]; 303 [_paymentRequestCoordinator stop];
287 _paymentRequestCoordinator.reset(); 304 _paymentRequestCoordinator.reset();
288 } 305 }
289 306
(...skipping 17 matching lines...) Expand all
307 #pragma mark - PaymentRequestCoordinatorDelegate methods 324 #pragma mark - PaymentRequestCoordinatorDelegate methods
308 325
309 - (void)paymentRequestCoordinatorDidCancel { 326 - (void)paymentRequestCoordinatorDidCancel {
310 [self cancelRequest]; 327 [self cancelRequest];
311 } 328 }
312 329
313 - (void)paymentRequestCoordinatorDidConfirm: 330 - (void)paymentRequestCoordinatorDidConfirm:
314 (web::PaymentResponse)paymentResponse { 331 (web::PaymentResponse)paymentResponse {
315 [_paymentRequestJsManager resolveRequestPromise:paymentResponse 332 [_paymentRequestJsManager resolveRequestPromise:paymentResponse
316 completionHandler:nil]; 333 completionHandler:nil];
334
335 // Establish a timer that periodically prompts the JS manager to execute a
336 // noop. This works around an issue where the JS event queue is blocked while
337 // presenting the Payment Request UI.
338 _unblockEventQueueTimer.reset(
339 [[NSTimer scheduledTimerWithTimeInterval:kNoopInterval
340 target:_paymentRequestJsManager
341 selector:@selector(executeNoop)
342 userInfo:nil
343 repeats:YES] retain]);
344
345 // Per the spec, if the page does not call PaymentResponse.complete() within
346 // some timeout period, user agents may behave as if the complete() method was
347 // called with no arguments.
348 _paymentResponseTimeoutTimer.reset(
349 [[NSTimer scheduledTimerWithTimeInterval:kTimeoutInterval
350 target:self
351 selector:@selector(handleResponseComplete)
352 userInfo:nil
353 repeats:NO] retain]);
317 } 354 }
318 355
319 #pragma mark - CRWWebStateObserver methods 356 #pragma mark - CRWWebStateObserver methods
320 357
321 - (void)webState:(web::WebState*)webState 358 - (void)webState:(web::WebState*)webState
322 didCommitNavigationWithDetails: 359 didCommitNavigationWithDetails:
323 (const web::LoadCommittedDetails&)load_details { 360 (const web::LoadCommittedDetails&)load_details {
324 [self dismissUI]; 361 [self dismissUI];
325 _isScriptInjected = NO; 362 _isScriptInjected = NO;
326 [self enableCurrentWebState]; 363 [self enableCurrentWebState];
327 [self initializeWebViewForPaymentRequest]; 364 [self initializeWebViewForPaymentRequest];
328 } 365 }
329 366
330 @end 367 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698