1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
// Copyright 2019 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_PASSWORD_MANAGER_ANDROID_PASSWORD_GENERATION_CONTROLLER_IMPL_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_GENERATION_CONTROLLER_IMPL_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/password_manager/android/password_generation_controller.h"
#include "chrome/browser/touch_to_fill/password_manager/password_generation/android/touch_to_fill_password_generation_bridge.h"
#include "components/autofill/core/common/password_generation_util.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "ui/gfx/geometry/rect.h"
class ManualFillingController;
class TouchToFillPasswordGenerationController;
struct PasswordGenerationElementData;
namespace password_manager {
class ContentPasswordManagerDriver;
class PasswordManagerClient;
} // namespace password_manager
// In its current state, this class is not involved in the editing flow for
// a generated password.
//
// Use either PasswordGenerationController::GetOrCreate or
// PasswordGenerationController::GetIfExisting to obtain instances of this
// class.
class PasswordGenerationControllerImpl
: public PasswordGenerationController,
public content::WebContentsObserver,
public content::WebContentsUserData<PasswordGenerationControllerImpl> {
public:
using CreateTouchToFillGenerationControllerFactory = base::RepeatingCallback<
std::unique_ptr<TouchToFillPasswordGenerationController>()>;
PasswordGenerationControllerImpl(const PasswordGenerationControllerImpl&) =
delete;
PasswordGenerationControllerImpl& operator=(
const PasswordGenerationControllerImpl&) = delete;
~PasswordGenerationControllerImpl() override;
// PasswordGenerationController:
base::WeakPtr<password_manager::ContentPasswordManagerDriver>
GetActiveFrameDriver() const override;
void FocusedInputChanged(
bool is_field_eligible_for_generation,
base::WeakPtr<password_manager::ContentPasswordManagerDriver> driver)
override;
void OnAutomaticGenerationAvailable(
base::WeakPtr<password_manager::ContentPasswordManagerDriver>
target_frame_driver,
const autofill::password_generation::PasswordGenerationUIData& ui_data,
bool has_saved_credentials,
gfx::RectF element_bounds_in_screen_space) override;
void ShowManualGenerationDialog(
const password_manager::ContentPasswordManagerDriver* target_frame_driver,
const autofill::password_generation::PasswordGenerationUIData& ui_data)
override;
void OnGenerationRequested(
autofill::password_generation::PasswordGenerationType type) override;
void GeneratedPasswordAccepted(
const std::u16string& password,
base::WeakPtr<password_manager::ContentPasswordManagerDriver> driver,
autofill::password_generation::PasswordGenerationType type) override;
void GeneratedPasswordRejected(
autofill::password_generation::PasswordGenerationType type) override;
void HideBottomSheetIfNeeded() override;
// Creates the |TouchToFillPasswordGenerationController| with mocked bridge
// for testing.
std::unique_ptr<TouchToFillPasswordGenerationController>
CreateTouchToFillGenerationControllerForTesting(
std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge,
base::WeakPtr<ManualFillingController> manual_filling_controller)
override;
TouchToFillPasswordGenerationController*
GetTouchToFillGenerationControllerForTesting() override;
gfx::NativeWindow top_level_native_window() override;
content::WebContents* web_contents() override;
autofill::FieldSignature get_field_signature_for_testing() override;
autofill::FormSignature get_form_signature_for_testing() override;
// Like |CreateForWebContents|, it creates the controller and attaches it to
// the given |web_contents|. Additionally, it allows injecting mocks for
// testing.
static void CreateForWebContentsForTesting(
content::WebContents* web_contents,
password_manager::PasswordManagerClient* client,
base::WeakPtr<ManualFillingController> manual_filling_controller,
CreateTouchToFillGenerationControllerFactory
create_touch_to_fill_generation_controller);
protected:
// Callable in tests.
explicit PasswordGenerationControllerImpl(content::WebContents* web_contents);
private:
enum class TouchToFillState {
kNone,
kIsShowing,
kWasShown,
};
friend class content::WebContentsUserData<PasswordGenerationControllerImpl>;
// Constructor that allows to inject a mock or fake dependencies
PasswordGenerationControllerImpl(
content::WebContents* web_contents,
password_manager::PasswordManagerClient* client,
base::WeakPtr<ManualFillingController> manual_filling_controller,
CreateTouchToFillGenerationControllerFactory
create_touch_to_fill_generation_controller);
// content::WebContentsObserver:
// Called when the `content::WebContents` render frame is deleted.
// Ensures that the password generation bottom sheet is hidden when the frame
// is removed.
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
void WebContentsDestroyed() override;
std::unique_ptr<TouchToFillPasswordGenerationController>
CreateTouchToFillGenerationController();
// Checks if the given PasswordManagerDriver is the same as the one
// belonging to the currently considered active frame for generation.
// The active frame is the latest focused frame that received a field focus
// event.
bool IsActiveFrameDriver(
const password_manager::ContentPasswordManagerDriver* driver) const;
// Called to show the generation modal dialog. |manual| - whether the
// dialog was shown for a manual or automatic generation flow. This is used
// for metrics.
void ShowDialog(autofill::password_generation::PasswordGenerationType type);
bool TryToShowGenerationTouchToFill(bool has_saved_credentials);
bool ShowBottomSheet(
autofill::password_generation::PasswordGenerationType type);
void OnTouchToFillForGenerationDismissed();
// Resets the current active frame driver, as well as the dialog if shown
// and the generation element data.
void ResetFocusState();
// Sets the number of generation bottom sheet rejections in a row to 0.
// Expected to be called when user voluntary triggers password generation.
void ResetPasswordGenerationDismissBottomSheetCount();
// The PasswordManagerClient associated with the current `web_contents_`.
// Used to tell the renderer that manual generation was requested.
const raw_ptr<password_manager::PasswordManagerClient> client_;
// Data for the generation element used to generate the password.
std::unique_ptr<PasswordGenerationElementData> generation_element_data_;
// Password manager driver for the currently active frame. This is set
// when a password field focus event arrives from the renderer and unset
// whenever a focus event for a non-password field is received.
base::WeakPtr<password_manager::ContentPasswordManagerDriver>
active_frame_driver_;
// The manual filling controller object to forward client requests to.
base::WeakPtr<ManualFillingController> manual_filling_controller_;
std::unique_ptr<TouchToFillPasswordGenerationController>
touch_to_fill_generation_controller_;
// Creation callback for the password generation bottom sheet controller to
// facilitate testing.
CreateTouchToFillGenerationControllerFactory
create_touch_to_fill_generation_controller_;
// Whether manual generation was requested from the UI. Used to filter out
// unexpected or delayed manual generation responses from the renderer.
bool manual_generation_requested_ = false;
// Whether password generation bottom sheet was already shown.
TouchToFillState touch_to_fill_generation_state_ = TouchToFillState::kNone;
WEB_CONTENTS_USER_DATA_KEY_DECL();
};
#endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_GENERATION_CONTROLLER_IMPL_H_
|