| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/payments/content/payment_credential.h" |
| |
| #include <utility> |
| |
| #include "base/compiler_specific.h" |
| #include "base/feature_list.h" |
| #include "base/memory/ref_counted_memory.h" |
| #include "components/payments/content/payment_manifest_web_data_service.h" |
| #include "components/payments/core/secure_payment_confirmation_credential.h" |
| #include "content/public/browser/navigation_handle.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/content_features.h" |
| #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h" |
| |
| namespace payments { |
| |
| // static |
| bool PaymentCredential::IsFrameAllowedToUseSecurePaymentConfirmation( |
| content::RenderFrameHost* rfh) { |
| return rfh && rfh->IsActive() && |
| rfh->IsFeatureEnabled( |
| blink::mojom::PermissionsPolicyFeature::kPayment) && |
| base::FeatureList::IsEnabled(features::kSecurePaymentConfirmation); |
| } |
| |
| PaymentCredential::PaymentCredential( |
| content::RenderFrameHost& render_frame_host, |
| mojo::PendingReceiver<mojom::PaymentCredential> receiver, |
| scoped_refptr<PaymentManifestWebDataService> web_data_service) |
| : DocumentService(render_frame_host, std::move(receiver)), |
| web_data_service_(web_data_service) {} |
| |
| PaymentCredential::~PaymentCredential() { |
| Reset(); |
| } |
| |
| void PaymentCredential::StorePaymentCredential( |
| const std::vector<uint8_t>& credential_id, |
| const std::string& rp_id, |
| const std::vector<uint8_t>& user_id, |
| StorePaymentCredentialCallback callback) { |
| if (state_ != State::kIdle || !IsCurrentStateValid() || |
| credential_id.empty() || rp_id.empty() || user_id.empty()) { |
| Reset(); |
| std::move(callback).Run( |
| mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL); |
| return; |
| } |
| |
| RecordFirstSystemPromptResult( |
| SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted); |
| |
| storage_callback_ = std::move(callback); |
| state_ = State::kStoringCredential; |
| data_service_request_handle_ = |
| web_data_service_->AddSecurePaymentConfirmationCredential( |
| std::make_unique<SecurePaymentConfirmationCredential>(credential_id, |
| rp_id, user_id), |
| /*consumer=*/this); |
| } |
| |
| void PaymentCredential::OnWebDataServiceRequestDone( |
| WebDataServiceBase::Handle h, |
| std::unique_ptr<WDTypedResult> result) { |
| if (state_ != State::kStoringCredential || !IsCurrentStateValid() || |
| data_service_request_handle_ != h) { |
| Reset(); |
| return; |
| } |
| |
| auto callback = std::move(storage_callback_); |
| Reset(); |
| |
| std::move(callback).Run( |
| static_cast<WDResult<bool>*>(result.get())->GetValue() |
| ? mojom::PaymentCredentialStorageStatus::SUCCESS |
| : mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL); |
| } |
| |
| bool PaymentCredential::IsCurrentStateValid() const { |
| if (!IsFrameAllowedToUseSecurePaymentConfirmation(&render_frame_host()) || |
| !web_data_service_) { |
| return false; |
| } |
| |
| switch (state_) { |
| case State::kIdle: |
| return !storage_callback_ && !data_service_request_handle_; |
| |
| case State::kStoringCredential: |
| return storage_callback_ && data_service_request_handle_; |
| } |
| } |
| |
| void PaymentCredential::RecordFirstSystemPromptResult( |
| SecurePaymentConfirmationEnrollSystemPromptResult result) { |
| if (!is_system_prompt_result_recorded_) { |
| is_system_prompt_result_recorded_ = true; |
| RecordEnrollSystemPromptResult(result); |
| } |
| } |
| |
| void PaymentCredential::Reset() { |
| // Callbacks must either be run or disconnected before being destroyed, so |
| // run them if they are still connected. |
| if (storage_callback_) { |
| std::move(storage_callback_) |
| .Run(mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_CREDENTIAL); |
| } |
| |
| if (web_data_service_ && data_service_request_handle_) { |
| web_data_service_->CancelRequest(data_service_request_handle_.value()); |
| } |
| |
| data_service_request_handle_.reset(); |
| is_system_prompt_result_recorded_ = false; |
| state_ = State::kIdle; |
| } |
| |
| } // namespace payments |