blob: c5b167b9ef3cf958b84a0819affb258d217bd257 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_
#define CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_
#include <memory>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "chrome/browser/touch_to_fill/password_manager/touch_to_fill_controller_webauthn_delegate.h"
#include "chrome/browser/webauthn/shared_types.h"
#include "components/password_manager/core/browser/passkey_credential.h"
#include "components/password_manager/core/browser/password_form.h"
#include "components/webauthn/android/webauthn_client_android.h"
#include "content/public/browser/global_routing_id.h"
namespace content {
class RenderFrameHost;
class WebContents;
} // namespace content
namespace device {
class DiscoverableCredentialMetadata;
}
namespace password_manager {
class KeyboardReplacingSurfaceVisibilityController;
}
class PasswordCredentialController;
class TouchToFillController;
// Helper class for connecting the autofill implementation to the WebAuthn
// request handling for Conditional UI on Android. This is attached to a
// WebContents via SetUserData. It caches a callback that will complete the
// WebAuthn 'get' request when a user selects a credential.
class WebAuthnRequestDelegateAndroid
: public base::SupportsUserData::Data,
public TouchToFillControllerWebAuthnDelegate::CredentialReceiver {
public:
explicit WebAuthnRequestDelegateAndroid(content::WebContents* web_contents);
WebAuthnRequestDelegateAndroid(const WebAuthnRequestDelegateAndroid&) =
delete;
WebAuthnRequestDelegateAndroid& operator=(
const WebAuthnRequestDelegateAndroid&) = delete;
~WebAuthnRequestDelegateAndroid() override;
// Called when a Web Authentication GetAssertion request is received. This
// provides password and passkey callbacks that will complete the request if
// and when a user selects a credential from a touch to fill sheet.
// `hybrid_closure` is invoked if the user selects the option to trigger the
// hybrid transport for passkeys.
// `non_credential_callback` is invoked if the sheet if the request will be
// completed for any other reason.
void OnWebAuthnRequestPending(
content::RenderFrameHost* frame_host,
std::vector<device::DiscoverableCredentialMetadata> credentials,
webauthn::AssertionMediationType mediation_type,
base::RepeatingCallback<void(const std::vector<uint8_t>& id)>
passkey_callback,
base::RepeatingCallback<void(std::u16string_view, std::u16string_view)>
password_callback,
base::RepeatingClosure hybrid_closure,
base::RepeatingCallback<void(webauthn::NonCredentialReturnReason)>
non_credential_callback);
// Called when an outstanding request is ended, either because it was aborted
// by the RP, or because it completed successfully. Its main purpose is to
// clean up conditional UI state.
void CleanupWebAuthnRequest(content::RenderFrameHost* frame_host);
// TouchToFillControllerWebAuthnDelegate::CredentialReceiver:
void OnWebAuthnAccountSelected(const std::vector<uint8_t>& id) override;
void OnPasswordCredentialSelected(
const PasswordCredentialPair& password_credential) override;
void OnCredentialSelectionDeclined() override;
void OnHybridSignInSelected() override;
content::WebContents* web_contents() override;
// Returns a delegate associated with the |web_contents|. It creates one if
// one does not already exist.
// The delegate is destroyed along with the WebContents and so should not be
// cached.
static WebAuthnRequestDelegateAndroid* GetRequestDelegate(
content::WebContents* web_contents);
private:
// This takes the RenderFrameHost's GlobalID rather than a pointer, so that
// it can be called asynchronously without having to worry about lifetimes.
void MaybeShowTouchToFillSheet(
content::GlobalRenderFrameHostId render_frame_host_id,
bool isImmediate,
std::vector<password_manager::PasskeyCredential> passkey_credentials,
std::vector<std::unique_ptr<password_manager::PasswordForm>>
password_credentials);
// Completion callbacks for the request. These can be null if
// `CleanupWebAuthnRequest` has been called, probably due to the credential
// request being cancelled.
base::RepeatingCallback<void(const std::vector<uint8_t>& id)>
passkey_callback_;
base::RepeatingCallback<void(std::u16string_view, std::u16string_view)>
password_callback_;
base::RepeatingClosure hybrid_closure_;
base::RepeatingCallback<void(webauthn::NonCredentialReturnReason)>
non_credential_callback_;
// Controller for using the Touch To Fill bottom sheet for non-conditional
// requests.
std::unique_ptr<TouchToFillController> touch_to_fill_controller_;
std::unique_ptr<
password_manager::KeyboardReplacingSurfaceVisibilityController>
visibility_controller_;
// The WebContents that has this object in its userdata.
raw_ptr<content::WebContents> web_contents_;
bool conditional_request_in_progress_ = false;
std::unique_ptr<PasswordCredentialController> password_controller_;
base::WeakPtrFactory<WebAuthnRequestDelegateAndroid> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_