| 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 #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 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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |