chromium/chrome/browser/webauthn/android/webauthn_request_delegate_android.h

// 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/supports_user_data.h"

namespace content {
class RenderFrameHost;
class WebContents;
}  // namespace content

namespace device {
class DiscoverableCredentialMetadata;
}

namespace password_manager {
class KeyboardReplacingSurfaceVisibilityController;
}

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:
  explicit WebAuthnRequestDelegateAndroid(content::WebContents* web_contents);

  WebAuthnRequestDelegateAndroid(const WebAuthnRequestDelegateAndroid&) =
      delete;
  WebAuthnRequestDelegateAndroid& operator=(
      const WebAuthnRequestDelegateAndroid&) = delete;

  ~WebAuthnRequestDelegateAndroid() override;

  // Called when a Web Authentication Conditional UI request is received. This
  // provides a callback that will complete the request if and when a user
  // selects a credential from a form autofill dialog, and also a closure that
  // is invoked if the user starts a hybrid authentication.
  void OnWebAuthnRequestPending(
      content::RenderFrameHost* frame_host,
      const std::vector<device::DiscoverableCredentialMetadata>& credentials,
      bool is_conditional_request,
      base::RepeatingCallback<void(const std::vector<uint8_t>& id)>
          get_assertion_callback,
      base::RepeatingClosure hybrid_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);

  // Tells the WebAuthn Java implementation that the user has selected a Web
  // Authentication credential from a dialog, and provides the credential ID
  // for the selected credential.
  virtual void OnWebAuthnAccountSelected(const std::vector<uint8_t>& id);

  // Tells the WebAuthn Java implementation the the user has selected the
  // option for hybrid sign-in, which should be handled by the platform.
  virtual void ShowHybridSignIn();

  // Returns the WebContents that owns this object.
  content::WebContents* web_contents();

  // 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:
  base::RepeatingCallback<void(const std::vector<uint8_t>& user_id)>
      get_assertion_callback_;
  base::RepeatingClosure hybrid_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;
};

#endif  // CHROME_BROWSER_WEBAUTHN_ANDROID_WEBAUTHN_REQUEST_DELEGATE_ANDROID_H_