Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |