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

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: 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 #include "ios/web/public/ssl_status.h" 25 #include "ios/web/public/ssl_status.h"
26 #import "ios/web/public/url_scheme_util.h" 26 #import "ios/web/public/url_scheme_util.h"
27 #import "ios/web/public/web_state/crw_web_view_proxy.h" 27 #import "ios/web/public/web_state/crw_web_view_proxy.h"
28 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" 28 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
29 #include "ios/web/public/web_state/url_verification_constants.h" 29 #include "ios/web/public/web_state/url_verification_constants.h"
30 #include "ios/web/public/web_state/web_state.h" 30 #include "ios/web/public/web_state/web_state.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 ()<PaymentRequestCoordinatorDelegate, 45 @interface PaymentRequestManager ()<PaymentRequestCoordinatorDelegate,
38 PaymentRequestWebStateDelegate> { 46 PaymentRequestWebStateDelegate> {
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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 290
276 [_paymentRequestCoordinator start]; 291 [_paymentRequestCoordinator start];
277 292
278 return YES; 293 return YES;
279 } 294 }
280 295
281 - (BOOL)handleResponseComplete { 296 - (BOOL)handleResponseComplete {
282 // TODO(crbug.com/602666): Check that there *is* a pending response here. 297 // TODO(crbug.com/602666): Check that there *is* a pending response here.
283 // TODO(crbug.com/602666): Indicate success or failure in the UI. 298 // TODO(crbug.com/602666): Indicate success or failure in the UI.
284 299
300 [_unblockEventQueueTimer invalidate];
301 [_paymentResponseTimeoutTimer invalidate];
302
285 [self dismissUI]; 303 [self dismissUI];
286 304
287 // TODO(crbug.com/602666): Reject the promise on failure.
288 [_paymentRequestJsManager resolveResponsePromise:nil]; 305 [_paymentRequestJsManager resolveResponsePromise:nil];
289 306
290 return YES; 307 return YES;
291 } 308 }
292 309
293 - (void)dismissUI { 310 - (void)dismissUI {
294 [_paymentRequestCoordinator stop]; 311 [_paymentRequestCoordinator stop];
295 _paymentRequestCoordinator.reset(); 312 _paymentRequestCoordinator.reset();
296 } 313 }
297 314
(...skipping 17 matching lines...) Expand all
315 #pragma mark - PaymentRequestCoordinatorDelegate methods 332 #pragma mark - PaymentRequestCoordinatorDelegate methods
316 333
317 - (void)paymentRequestCoordinatorDidCancel { 334 - (void)paymentRequestCoordinatorDidCancel {
318 [self cancelRequest]; 335 [self cancelRequest];
319 } 336 }
320 337
321 - (void)paymentRequestCoordinatorDidConfirm: 338 - (void)paymentRequestCoordinatorDidConfirm:
322 (web::PaymentResponse)paymentResponse { 339 (web::PaymentResponse)paymentResponse {
323 [_paymentRequestJsManager resolveRequestPromise:paymentResponse 340 [_paymentRequestJsManager resolveRequestPromise:paymentResponse
324 completionHandler:nil]; 341 completionHandler:nil];
342
343 // Establish a timer that periodically prompts the JS manager to execute a
344 // noop. This works around an issue where the JS event queue is blocked while
345 // presenting the Payment Request UI.
346 _unblockEventQueueTimer.reset(
347 [[NSTimer scheduledTimerWithTimeInterval:kNoopInterval
348 target:_paymentRequestJsManager
349 selector:@selector(executeNoop)
350 userInfo:nil
351 repeats:YES] retain]);
Moe 2017/01/16 21:52:58 is executeNoop what fixes the landscape issue? Why
Justin Donnelly 2017/01/18 19:36:21 Correct, this fixes the landscape issue. Switching
352
353 // Per the spec, if the page does not call PaymentResponse.complete() within
354 // some timeout period, user agents may behave as if the complete() method was
355 // called with no arguments.
356 _paymentResponseTimeoutTimer.reset(
357 [[NSTimer scheduledTimerWithTimeInterval:kTimeoutInterval
358 target:self
359 selector:@selector(handleResponseComplete)
360 userInfo:nil
361 repeats:NO] retain]);
325 } 362 }
326 363
327 #pragma mark - PaymentRequestWebStateDelegate methods 364 #pragma mark - PaymentRequestWebStateDelegate methods
328 365
329 - (void)pageLoadedWithStatus:(web::PageLoadCompletionStatus)loadStatus { 366 - (void)pageLoadedWithStatus:(web::PageLoadCompletionStatus)loadStatus {
330 if (loadStatus != web::PageLoadCompletionStatus::SUCCESS) 367 if (loadStatus != web::PageLoadCompletionStatus::SUCCESS)
331 return; 368 return;
332 369
333 [self dismissUI]; 370 [self dismissUI];
334 _isScriptInjected = NO; 371 _isScriptInjected = NO;
335 [self enableCurrentWebState]; 372 [self enableCurrentWebState];
336 } 373 }
337 374
338 @end 375 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698