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 #include "modules/payments/PaymentRequest.h" | 5 #include "modules/payments/PaymentRequest.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
| 8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 9 #include "bindings/core/v8/ScriptState.h" | 9 #include "bindings/core/v8/ScriptState.h" |
| 10 #include "bindings/core/v8/V8StringResource.h" | 10 #include "bindings/core/v8/V8StringResource.h" |
| 11 #include "bindings/modules/v8/V8AndroidPayMethodData.h" | 11 #include "bindings/modules/v8/V8AndroidPayMethodData.h" |
| 12 #include "bindings/modules/v8/V8BasicCardRequest.h" | |
| 12 #include "bindings/modules/v8/V8PaymentDetails.h" | 13 #include "bindings/modules/v8/V8PaymentDetails.h" |
| 13 #include "core/EventTypeNames.h" | 14 #include "core/EventTypeNames.h" |
| 14 #include "core/dom/DOMException.h" | 15 #include "core/dom/DOMException.h" |
| 15 #include "core/dom/ExceptionCode.h" | 16 #include "core/dom/ExceptionCode.h" |
| 16 #include "core/events/Event.h" | 17 #include "core/events/Event.h" |
| 17 #include "core/events/EventQueue.h" | 18 #include "core/events/EventQueue.h" |
| 18 #include "core/frame/FrameOwner.h" | 19 #include "core/frame/FrameOwner.h" |
| 19 #include "core/html/HTMLIFrameElement.h" | 20 #include "core/html/HTMLIFrameElement.h" |
| 20 #include "modules/EventTargetModulesNames.h" | 21 #include "modules/EventTargetModulesNames.h" |
| 21 #include "modules/payments/AndroidPayMethodData.h" | 22 #include "modules/payments/AndroidPayMethodData.h" |
| 22 #include "modules/payments/AndroidPayTokenization.h" | 23 #include "modules/payments/AndroidPayTokenization.h" |
| 24 #include "modules/payments/BasicCardRequest.h" | |
| 23 #include "modules/payments/HTMLIFrameElementPayments.h" | 25 #include "modules/payments/HTMLIFrameElementPayments.h" |
| 24 #include "modules/payments/PaymentAddress.h" | 26 #include "modules/payments/PaymentAddress.h" |
| 25 #include "modules/payments/PaymentItem.h" | 27 #include "modules/payments/PaymentItem.h" |
| 26 #include "modules/payments/PaymentRequestUpdateEvent.h" | 28 #include "modules/payments/PaymentRequestUpdateEvent.h" |
| 27 #include "modules/payments/PaymentResponse.h" | 29 #include "modules/payments/PaymentResponse.h" |
| 28 #include "modules/payments/PaymentShippingOption.h" | 30 #include "modules/payments/PaymentShippingOption.h" |
| 29 #include "modules/payments/PaymentsValidators.h" | 31 #include "modules/payments/PaymentsValidators.h" |
| 30 #include "mojo/public/cpp/bindings/interface_request.h" | 32 #include "mojo/public/cpp/bindings/interface_request.h" |
| 31 #include "mojo/public/cpp/bindings/wtf_array.h" | 33 #include "mojo/public/cpp/bindings/wtf_array.h" |
| 32 #include "platform/RuntimeEnabledFeatures.h" | 34 #include "platform/RuntimeEnabledFeatures.h" |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 | 112 |
| 111 return output; | 113 return output; |
| 112 } | 114 } |
| 113 }; | 115 }; |
| 114 | 116 |
| 115 } // namespace mojo | 117 } // namespace mojo |
| 116 | 118 |
| 117 namespace blink { | 119 namespace blink { |
| 118 namespace { | 120 namespace { |
| 119 | 121 |
| 120 using payments::mojom::blink::AndroidPayCardNetwork; | |
| 121 using payments::mojom::blink::AndroidPayTokenization; | |
| 122 | |
| 123 // If the website does not call complete() 60 seconds after show() has been | 122 // If the website does not call complete() 60 seconds after show() has been |
| 124 // resolved, then behave as if the website called complete("fail"). | 123 // resolved, then behave as if the website called complete("fail"). |
| 125 static const int completeTimeoutSeconds = 60; | 124 static const int completeTimeoutSeconds = 60; |
| 126 | 125 |
| 127 const struct { | |
| 128 const AndroidPayCardNetwork code; | |
| 129 const char* name; | |
| 130 } kAndroidPayNetwork[] = {{AndroidPayCardNetwork::AMEX, "AMEX"}, | |
| 131 {AndroidPayCardNetwork::DISCOVER, "DISCOVER"}, | |
| 132 {AndroidPayCardNetwork::MASTERCARD, "MASTERCARD"}, | |
| 133 {AndroidPayCardNetwork::VISA, "VISA"}}; | |
| 134 | |
| 135 const struct { | |
| 136 const AndroidPayTokenization code; | |
| 137 const char* name; | |
| 138 } kAndroidPayTokenization[] = { | |
| 139 {AndroidPayTokenization::GATEWAY_TOKEN, "GATEWAY_TOKEN"}, | |
| 140 {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}}; | |
| 141 | |
| 142 // Validates ShippingOption or PaymentItem, which happen to have identical | 126 // Validates ShippingOption or PaymentItem, which happen to have identical |
| 143 // fields, except for "id", which is present only in ShippingOption. | 127 // fields, except for "id", which is present only in ShippingOption. |
| 144 template <typename T> | 128 template <typename T> |
| 145 void validateShippingOptionOrPaymentItem(const T& item, | 129 void validateShippingOptionOrPaymentItem(const T& item, |
| 146 ExceptionState& exceptionState) { | 130 ExceptionState& exceptionState) { |
| 147 if (!item.hasLabel() || item.label().isEmpty()) { | 131 if (!item.hasLabel() || item.label().isEmpty()) { |
| 148 exceptionState.throwTypeError("Item label required"); | 132 exceptionState.throwTypeError("Item label required"); |
| 149 return; | 133 return; |
| 150 } | 134 } |
| 151 | 135 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 return; | 214 return; |
| 231 | 215 |
| 232 if (input.amount().value()[0] == '-') { | 216 if (input.amount().value()[0] == '-') { |
| 233 exceptionState.throwTypeError("Total amount value should be non-negative"); | 217 exceptionState.throwTypeError("Total amount value should be non-negative"); |
| 234 return; | 218 return; |
| 235 } | 219 } |
| 236 | 220 |
| 237 output = payments::mojom::blink::PaymentItem::From(input); | 221 output = payments::mojom::blink::PaymentItem::From(input); |
| 238 } | 222 } |
| 239 | 223 |
| 240 void maybeSetAndroidPayMethodData(const ScriptValue& input, | 224 // Parses Android Pay data to avoid parsing JSON in the browser. |
| 241 PaymentMethodDataPtr& output, | 225 void setAndroidPayMethodData(const ScriptValue& input, |
| 242 ExceptionState& exceptionState) { | 226 PaymentMethodDataPtr& output, |
| 227 ExceptionState& exceptionState) { | |
| 243 AndroidPayMethodData androidPay; | 228 AndroidPayMethodData androidPay; |
| 244 DummyExceptionStateForTesting dummyExceptionState; | |
| 245 V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay, | 229 V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay, |
| 246 dummyExceptionState); | 230 exceptionState); |
| 247 if (dummyExceptionState.hadException()) | 231 if (exceptionState.hadException()) |
| 248 return; | 232 return; |
| 249 | 233 |
| 250 if (androidPay.hasEnvironment() && androidPay.environment() == "TEST") | 234 if (androidPay.hasEnvironment() && androidPay.environment() == "TEST") |
| 251 output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST; | 235 output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST; |
| 252 | 236 |
| 253 output->merchant_name = androidPay.merchantName(); | 237 output->merchant_name = androidPay.merchantName(); |
| 254 output->merchant_id = androidPay.merchantId(); | 238 output->merchant_id = androidPay.merchantId(); |
| 255 | 239 |
| 256 // 0 means the merchant did not specify or it was an invalid value | 240 // 0 means the merchant did not specify or it was an invalid value |
| 257 output->min_google_play_services_version = 0; | 241 output->min_google_play_services_version = 0; |
| 258 if (androidPay.hasMinGooglePlayServicesVersion()) { | 242 if (androidPay.hasMinGooglePlayServicesVersion()) { |
| 259 bool ok = false; | 243 bool ok = false; |
| 260 int minGooglePlayServicesVersion = | 244 int minGooglePlayServicesVersion = |
| 261 androidPay.minGooglePlayServicesVersion().toIntStrict(&ok); | 245 androidPay.minGooglePlayServicesVersion().toIntStrict(&ok); |
| 262 if (ok) { | 246 if (ok) { |
| 263 output->min_google_play_services_version = minGooglePlayServicesVersion; | 247 output->min_google_play_services_version = minGooglePlayServicesVersion; |
| 264 } | 248 } |
| 265 } | 249 } |
| 266 | 250 |
| 267 if (androidPay.hasAllowedCardNetworks()) { | 251 if (androidPay.hasAllowedCardNetworks()) { |
| 252 using payments::mojom::blink::AndroidPayCardNetwork; | |
| 253 | |
| 254 const struct { | |
| 255 const AndroidPayCardNetwork code; | |
| 256 const char* const name; | |
| 257 } androidPayNetwork[] = {{AndroidPayCardNetwork::AMEX, "AMEX"}, | |
| 258 {AndroidPayCardNetwork::DISCOVER, "DISCOVER"}, | |
| 259 {AndroidPayCardNetwork::MASTERCARD, "MASTERCARD"}, | |
| 260 {AndroidPayCardNetwork::VISA, "VISA"}}; | |
| 261 | |
| 268 for (const String& allowedCardNetwork : androidPay.allowedCardNetworks()) { | 262 for (const String& allowedCardNetwork : androidPay.allowedCardNetworks()) { |
| 269 for (size_t i = 0; i < arraysize(kAndroidPayNetwork); ++i) { | 263 for (size_t i = 0; i < arraysize(androidPayNetwork); ++i) { |
| 270 if (allowedCardNetwork == kAndroidPayNetwork[i].name) { | 264 if (allowedCardNetwork == androidPayNetwork[i].name) { |
| 271 output->allowed_card_networks.append(kAndroidPayNetwork[i].code); | 265 output->allowed_card_networks.append(androidPayNetwork[i].code); |
| 272 break; | 266 break; |
| 273 } | 267 } |
| 274 } | 268 } |
| 275 } | 269 } |
| 276 } | 270 } |
| 277 | 271 |
| 278 if (androidPay.hasPaymentMethodTokenizationParameters()) { | 272 if (androidPay.hasPaymentMethodTokenizationParameters()) { |
| 279 const blink::AndroidPayTokenization& tokenization = | 273 const blink::AndroidPayTokenization& tokenization = |
| 280 androidPay.paymentMethodTokenizationParameters(); | 274 androidPay.paymentMethodTokenizationParameters(); |
| 281 output->tokenization_type = | 275 output->tokenization_type = |
| 282 payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED; | 276 payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED; |
| 283 if (tokenization.hasTokenizationType()) { | 277 if (tokenization.hasTokenizationType()) { |
| 284 for (size_t i = 0; i < arraysize(kAndroidPayTokenization); ++i) { | 278 using payments::mojom::blink::AndroidPayTokenization; |
| 285 if (tokenization.tokenizationType() == | 279 |
| 286 kAndroidPayTokenization[i].name) { | 280 const struct { |
| 287 output->tokenization_type = kAndroidPayTokenization[i].code; | 281 const AndroidPayTokenization code; |
| 282 const char* const name; | |
| 283 } androidPayTokenization[] = { | |
| 284 {AndroidPayTokenization::GATEWAY_TOKEN, "GATEWAY_TOKEN"}, | |
| 285 {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}}; | |
| 286 | |
| 287 for (size_t i = 0; i < arraysize(androidPayTokenization); ++i) { | |
| 288 if (tokenization.tokenizationType() == androidPayTokenization[i].name) { | |
| 289 output->tokenization_type = androidPayTokenization[i].code; | |
| 288 break; | 290 break; |
| 289 } | 291 } |
| 290 } | 292 } |
| 291 } | 293 } |
| 292 | 294 |
| 293 if (tokenization.hasParameters()) { | 295 if (tokenization.hasParameters()) { |
| 294 const Vector<String>& keys = | 296 const Vector<String>& keys = |
| 295 tokenization.parameters().getPropertyNames(exceptionState); | 297 tokenization.parameters().getPropertyNames(exceptionState); |
| 296 if (exceptionState.hadException()) | 298 if (exceptionState.hadException()) |
| 297 return; | 299 return; |
| 298 String value; | 300 String value; |
| 299 for (const String& key : keys) { | 301 for (const String& key : keys) { |
| 300 if (!DictionaryHelper::get(tokenization.parameters(), key, value)) | 302 if (!DictionaryHelper::get(tokenization.parameters(), key, value)) |
| 301 continue; | 303 continue; |
| 302 output->parameters.append( | 304 output->parameters.append( |
| 303 payments::mojom::blink::AndroidPayTokenizationParameter::New()); | 305 payments::mojom::blink::AndroidPayTokenizationParameter::New()); |
| 304 output->parameters.back()->key = key; | 306 output->parameters.back()->key = key; |
| 305 output->parameters.back()->value = value; | 307 output->parameters.back()->value = value; |
| 306 } | 308 } |
| 307 } | 309 } |
| 308 } | 310 } |
| 309 } | 311 } |
| 310 | 312 |
| 311 void stringifyAndParseMethodSpecificData(const ScriptValue& input, | 313 // Parses basic-card data to avoid parsing JSON in the browser. |
| 314 void setBasicCardMethodData(const ScriptValue& input, | |
| 315 PaymentMethodDataPtr& output, | |
| 316 ExceptionState& exceptionState) { | |
| 317 BasicCardRequest basicCard; | |
| 318 V8BasicCardRequest::toImpl(input.isolate(), input.v8Value(), basicCard, | |
| 319 exceptionState); | |
| 320 if (exceptionState.hadException()) | |
| 321 return; | |
| 322 | |
| 323 if (basicCard.hasSupportedNetworks()) { | |
| 324 using payments::mojom::blink::BasicCardNetwork; | |
| 325 | |
| 326 const struct { | |
| 327 const BasicCardNetwork code; | |
| 328 const char* const name; | |
| 329 } basicCardNetworks[] = {{BasicCardNetwork::AMEX, "amex"}, | |
| 330 {BasicCardNetwork::DINERS, "diners"}, | |
| 331 {BasicCardNetwork::DISCOVER, "discover"}, | |
| 332 {BasicCardNetwork::JCB, "jcb"}, | |
| 333 {BasicCardNetwork::MASTERCARD, "mastercard"}, | |
| 334 {BasicCardNetwork::UNIONPAY, "unionpay"}, | |
| 335 {BasicCardNetwork::VISA, "visa"}}; | |
| 336 | |
| 337 for (const String& network : basicCard.supportedNetworks()) { | |
| 338 for (size_t i = 0; i < arraysize(basicCardNetworks); ++i) { | |
| 339 if (network == basicCardNetworks[i].name) { | |
| 340 output->supported_networks.append(basicCardNetworks[i].code); | |
| 341 break; | |
| 342 } | |
| 343 } | |
| 344 } | |
| 345 } | |
| 346 | |
| 347 if (basicCard.hasSupportedTypes()) { | |
| 348 using payments::mojom::blink::BasicCardType; | |
| 349 | |
| 350 const struct { | |
| 351 const BasicCardType code; | |
| 352 const char* const name; | |
| 353 } basicCardTypes[] = {{BasicCardType::CREDIT, "credit"}, | |
| 354 {BasicCardType::DEBIT, "debit"}, | |
| 355 {BasicCardType::PREPAID, "prepaid"}}; | |
| 356 | |
| 357 for (const String& type : basicCard.supportedTypes()) { | |
| 358 for (size_t i = 0; i < arraysize(basicCardTypes); ++i) { | |
| 359 if (type == basicCardTypes[i].name) { | |
| 360 output->supported_types.append(basicCardTypes[i].code); | |
| 361 break; | |
| 362 } | |
| 363 } | |
| 364 } | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 void stringifyAndParseMethodSpecificData(const Vector<String>& supportedMethods, | |
| 369 const ScriptValue& input, | |
| 312 PaymentMethodDataPtr& output, | 370 PaymentMethodDataPtr& output, |
| 313 ExceptionState& exceptionState) { | 371 ExceptionState& exceptionState) { |
| 314 DCHECK(!input.isEmpty()); | 372 DCHECK(!input.isEmpty()); |
| 315 if (!input.v8Value()->IsObject() || input.v8Value()->IsArray()) { | 373 if (!input.v8Value()->IsObject() || input.v8Value()->IsArray()) { |
| 316 exceptionState.throwTypeError("Data should be a JSON-serializable object"); | 374 exceptionState.throwTypeError("Data should be a JSON-serializable object"); |
| 317 return; | 375 return; |
| 318 } | 376 } |
| 319 | 377 |
| 320 v8::Local<v8::String> value; | 378 v8::Local<v8::String> value; |
| 321 if (!v8::JSON::Stringify(input.context(), input.v8Value().As<v8::Object>()) | 379 if (!v8::JSON::Stringify(input.context(), input.v8Value().As<v8::Object>()) |
| 322 .ToLocal(&value)) { | 380 .ToLocal(&value)) { |
| 323 exceptionState.throwTypeError( | 381 exceptionState.throwTypeError( |
| 324 "Unable to parse payment method specific data"); | 382 "Unable to parse payment method specific data"); |
| 325 return; | 383 return; |
| 326 } | 384 } |
| 327 | 385 |
| 328 output->stringified_data = | 386 output->stringified_data = |
| 329 v8StringToWebCoreString<String>(value, DoNotExternalize); | 387 v8StringToWebCoreString<String>(value, DoNotExternalize); |
| 330 maybeSetAndroidPayMethodData(input, output, exceptionState); | 388 |
| 389 if (supportedMethods.contains("https://android.com/pay")) { | |
| 390 setAndroidPayMethodData(input, output, exceptionState); | |
| 391 if (exceptionState.hadException()) | |
|
Marijn Kruisselbrink
2017/01/05 22:38:03
I recently came across Source/bindings/core/v8/Exc
haraken
2017/01/06 00:04:17
I intentionally removed DummyExceptionStateForTest
Marijn Kruisselbrink
2017/01/06 00:16:07
I think the reason why exceptions are being ignore
| |
| 392 exceptionState.clearException(); | |
| 393 } | |
| 394 | |
| 395 if (RuntimeEnabledFeatures::paymentRequestBasicCardEnabled() && | |
| 396 supportedMethods.contains("basic-card")) { | |
| 397 setBasicCardMethodData(input, output, exceptionState); | |
| 398 if (exceptionState.hadException()) | |
| 399 exceptionState.clearException(); | |
| 400 } | |
| 331 } | 401 } |
| 332 | 402 |
| 333 void validateAndConvertPaymentDetailsModifiers( | 403 void validateAndConvertPaymentDetailsModifiers( |
| 334 const HeapVector<PaymentDetailsModifier>& input, | 404 const HeapVector<PaymentDetailsModifier>& input, |
| 335 Vector<PaymentDetailsModifierPtr>& output, | 405 Vector<PaymentDetailsModifierPtr>& output, |
| 336 ExceptionState& exceptionState) { | 406 ExceptionState& exceptionState) { |
| 337 if (input.isEmpty()) { | 407 if (input.isEmpty()) { |
| 338 exceptionState.throwTypeError( | 408 exceptionState.throwTypeError( |
| 339 "Must specify at least one payment details modifier"); | 409 "Must specify at least one payment details modifier"); |
| 340 return; | 410 return; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 362 "Must specify at least one payment method identifier"); | 432 "Must specify at least one payment method identifier"); |
| 363 return; | 433 return; |
| 364 } | 434 } |
| 365 | 435 |
| 366 output.back()->method_data = | 436 output.back()->method_data = |
| 367 payments::mojom::blink::PaymentMethodData::New(); | 437 payments::mojom::blink::PaymentMethodData::New(); |
| 368 output.back()->method_data->supported_methods = modifier.supportedMethods(); | 438 output.back()->method_data->supported_methods = modifier.supportedMethods(); |
| 369 | 439 |
| 370 if (modifier.hasData() && !modifier.data().isEmpty()) { | 440 if (modifier.hasData() && !modifier.data().isEmpty()) { |
| 371 stringifyAndParseMethodSpecificData( | 441 stringifyAndParseMethodSpecificData( |
| 372 modifier.data(), output.back()->method_data, exceptionState); | 442 modifier.supportedMethods(), modifier.data(), |
| 443 output.back()->method_data, exceptionState); | |
| 373 } else { | 444 } else { |
| 374 output.back()->method_data->stringified_data = ""; | 445 output.back()->method_data->stringified_data = ""; |
| 375 } | 446 } |
| 376 } | 447 } |
| 377 } | 448 } |
| 378 | 449 |
| 379 String getSelectedShippingOption( | 450 String getSelectedShippingOption( |
| 380 const Vector<PaymentShippingOptionPtr>& shippingOptions) { | 451 const Vector<PaymentShippingOptionPtr>& shippingOptions) { |
| 381 String result; | 452 String result; |
| 382 for (const PaymentShippingOptionPtr& shippingOption : shippingOptions) { | 453 for (const PaymentShippingOptionPtr& shippingOption : shippingOptions) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 if (paymentMethodData.supportedMethods().isEmpty()) { | 521 if (paymentMethodData.supportedMethods().isEmpty()) { |
| 451 exceptionState.throwTypeError( | 522 exceptionState.throwTypeError( |
| 452 "Must specify at least one payment method identifier"); | 523 "Must specify at least one payment method identifier"); |
| 453 return; | 524 return; |
| 454 } | 525 } |
| 455 | 526 |
| 456 output.append(payments::mojom::blink::PaymentMethodData::New()); | 527 output.append(payments::mojom::blink::PaymentMethodData::New()); |
| 457 output.back()->supported_methods = paymentMethodData.supportedMethods(); | 528 output.back()->supported_methods = paymentMethodData.supportedMethods(); |
| 458 | 529 |
| 459 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) { | 530 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) { |
| 460 stringifyAndParseMethodSpecificData(paymentMethodData.data(), | 531 stringifyAndParseMethodSpecificData(paymentMethodData.supportedMethods(), |
| 532 paymentMethodData.data(), | |
| 461 output.back(), exceptionState); | 533 output.back(), exceptionState); |
| 462 } else { | 534 } else { |
| 463 output.back()->stringified_data = ""; | 535 output.back()->stringified_data = ""; |
| 464 } | 536 } |
| 465 } | 537 } |
| 466 } | 538 } |
| 467 | 539 |
| 468 String getValidShippingType(const String& shippingType) { | 540 String getValidShippingType(const String& shippingType) { |
| 469 static const char* const validValues[] = { | 541 static const char* const validValues[] = { |
| 470 "shipping", "delivery", "pickup", | 542 "shipping", "delivery", "pickup", |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 920 m_completeResolver.clear(); | 992 m_completeResolver.clear(); |
| 921 m_showResolver.clear(); | 993 m_showResolver.clear(); |
| 922 m_abortResolver.clear(); | 994 m_abortResolver.clear(); |
| 923 m_canMakePaymentResolver.clear(); | 995 m_canMakePaymentResolver.clear(); |
| 924 if (m_clientBinding.is_bound()) | 996 if (m_clientBinding.is_bound()) |
| 925 m_clientBinding.Close(); | 997 m_clientBinding.Close(); |
| 926 m_paymentProvider.reset(); | 998 m_paymentProvider.reset(); |
| 927 } | 999 } |
| 928 | 1000 |
| 929 } // namespace blink | 1001 } // namespace blink |
| OLD | NEW |