Commit 1c7b996b authored by Ioana Pandele's avatar Ioana Pandele Committed by Commit Bot

[Mfill Android] Ensure generation accepted message is sent to the same frame

A pointer to the PasswordManagerDriver is sent to the modal dialog, which
passes it back to the generation controller when the user accepts the
generated password. The driver is frame scoped and is used to communicate
back to the renderer that the password was accepted.

Bug:835234, 954196

Change-Id: If9ddf66f5466f5f22a90bbb5ff7897f28ce236df
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1571664
Commit-Queue: Ioana Pandele <ioanap@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#652186}
parent 28e5a8a1
...@@ -53,7 +53,9 @@ class MockPasswordGenerationController : public PasswordGenerationController { ...@@ -53,7 +53,9 @@ class MockPasswordGenerationController : public PasswordGenerationController {
const base::WeakPtr<password_manager::PasswordManagerDriver>&)); const base::WeakPtr<password_manager::PasswordManagerDriver>&));
MOCK_METHOD0(OnGenerationElementLostFocus, void()); MOCK_METHOD0(OnGenerationElementLostFocus, void());
MOCK_METHOD0(OnGenerationRequested, void()); MOCK_METHOD0(OnGenerationRequested, void());
MOCK_METHOD1(GeneratedPasswordAccepted, void(const base::string16&)); MOCK_METHOD2(GeneratedPasswordAccepted,
void(const base::string16&,
base::WeakPtr<password_manager::PasswordManagerDriver>));
MOCK_METHOD0(GeneratedPasswordRejected, void()); MOCK_METHOD0(GeneratedPasswordRejected, void());
MOCK_CONST_METHOD0(top_level_native_window, gfx::NativeWindow()); MOCK_CONST_METHOD0(top_level_native_window, gfx::NativeWindow());
}; };
......
...@@ -69,7 +69,10 @@ class PasswordGenerationController { ...@@ -69,7 +69,10 @@ class PasswordGenerationController {
virtual void OnGenerationRequested() = 0; virtual void OnGenerationRequested() = 0;
// Called from the modal dialog if the user accepted the generated password. // Called from the modal dialog if the user accepted the generated password.
virtual void GeneratedPasswordAccepted(const base::string16& password) = 0; // |driver| is used to communicate the message back to the renderer.
virtual void GeneratedPasswordAccepted(
const base::string16& password,
base::WeakPtr<password_manager::PasswordManagerDriver> driver) = 0;
// Called from the modal dialog if the user rejected the generated password. // Called from the modal dialog if the user rejected the generated password.
virtual void GeneratedPasswordRejected() = 0; virtual void GeneratedPasswordRejected() = 0;
......
...@@ -97,6 +97,7 @@ void PasswordGenerationControllerImpl::OnGenerationElementLostFocus() { ...@@ -97,6 +97,7 @@ void PasswordGenerationControllerImpl::OnGenerationElementLostFocus() {
if (manual_filling_controller_ && generation_element_data_) { if (manual_filling_controller_ && generation_element_data_) {
manual_filling_controller_->OnAutomaticGenerationStatusChanged(false); manual_filling_controller_->OnAutomaticGenerationStatusChanged(false);
} }
target_frame_driver_ = nullptr;
generation_element_data_.reset(); generation_element_data_.reset();
} }
...@@ -116,15 +117,17 @@ void PasswordGenerationControllerImpl::OnGenerationRequested() { ...@@ -116,15 +117,17 @@ void PasswordGenerationControllerImpl::OnGenerationRequested() {
->ReportSpecPriorityForGeneratedPassword(generation_element_data_->form, ->ReportSpecPriorityForGeneratedPassword(generation_element_data_->form,
spec_priority); spec_priority);
} }
dialog_view_->Show(password); dialog_view_->Show(password, std::move(target_frame_driver_));
target_frame_driver_ = nullptr;
} }
void PasswordGenerationControllerImpl::GeneratedPasswordAccepted( void PasswordGenerationControllerImpl::GeneratedPasswordAccepted(
const base::string16& password) { const base::string16& password,
if (!target_frame_driver_) base::WeakPtr<password_manager::PasswordManagerDriver> driver) {
if (!driver)
return; return;
RecordGenerationDialogDismissal(true); RecordGenerationDialogDismissal(true);
target_frame_driver_->GeneratedPasswordAccepted(password); driver->GeneratedPasswordAccepted(password);
dialog_view_.reset(); dialog_view_.reset();
} }
......
...@@ -37,7 +37,9 @@ class PasswordGenerationControllerImpl ...@@ -37,7 +37,9 @@ class PasswordGenerationControllerImpl
override; override;
void OnGenerationElementLostFocus() override; void OnGenerationElementLostFocus() override;
void OnGenerationRequested() override; void OnGenerationRequested() override;
void GeneratedPasswordAccepted(const base::string16& password) override; void GeneratedPasswordAccepted(
const base::string16& password,
base::WeakPtr<password_manager::PasswordManagerDriver> driver) override;
void GeneratedPasswordRejected() override; void GeneratedPasswordRejected() override;
gfx::NativeWindow top_level_native_window() const override; gfx::NativeWindow top_level_native_window() const override;
......
...@@ -39,6 +39,7 @@ class MockPasswordManagerDriver ...@@ -39,6 +39,7 @@ class MockPasswordManagerDriver
MOCK_METHOD0(GetPasswordGenerationHelper, MOCK_METHOD0(GetPasswordGenerationHelper,
password_manager::PasswordGenerationFrameHelper*()); password_manager::PasswordGenerationFrameHelper*());
MOCK_METHOD1(GeneratedPasswordAccepted, void(const base::string16&));
private: private:
DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerDriver); DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerDriver);
...@@ -68,7 +69,9 @@ class MockPasswordGenerationDialogView ...@@ -68,7 +69,9 @@ class MockPasswordGenerationDialogView
public: public:
MockPasswordGenerationDialogView() = default; MockPasswordGenerationDialogView() = default;
MOCK_METHOD1(Show, void(base::string16&)); MOCK_METHOD2(Show,
void(base::string16&,
base::WeakPtr<password_manager::PasswordManagerDriver>));
private: private:
DISALLOW_COPY_AND_ASSIGN(MockPasswordGenerationDialogView); DISALLOW_COPY_AND_ASSIGN(MockPasswordGenerationDialogView);
...@@ -102,6 +105,10 @@ PasswordGenerationUIData GetTestGenerationUIData2() { ...@@ -102,6 +105,10 @@ PasswordGenerationUIData GetTestGenerationUIData2() {
return data; return data;
} }
MATCHER_P(PointsToSameAddress, expected, "") {
return arg.get() == expected;
}
} // namespace } // namespace
class PasswordGenerationControllerTest class PasswordGenerationControllerTest
...@@ -236,7 +243,9 @@ TEST_F(PasswordGenerationControllerTest, ...@@ -236,7 +243,9 @@ TEST_F(PasswordGenerationControllerTest,
GeneratePassword(_, form_signature, field_signature, GeneratePassword(_, form_signature, field_signature,
uint32_t(new_ui_data.max_length), _)) uint32_t(new_ui_data.max_length), _))
.WillOnce(Return(generated_password)); .WillOnce(Return(generated_password));
EXPECT_CALL(*raw_dialog_view, Show(generated_password)); EXPECT_CALL(*raw_dialog_view,
Show(generated_password,
PointsToSameAddress(mock_password_manager_driver_.get())));
controller()->OnGenerationRequested(); controller()->OnGenerationRequested();
} }
...@@ -262,8 +271,30 @@ TEST_F(PasswordGenerationControllerTest, RecordsGeneratedPasswordAccepted) { ...@@ -262,8 +271,30 @@ TEST_F(PasswordGenerationControllerTest, RecordsGeneratedPasswordAccepted) {
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
controller()->OnGenerationRequested(); controller()->OnGenerationRequested();
controller()->GeneratedPasswordAccepted(test_password); controller()->GeneratedPasswordAccepted(
test_password, mock_password_manager_driver_->AsWeakPtr());
histogram_tester.ExpectUniqueSample( histogram_tester.ExpectUniqueSample(
"KeyboardAccessory.GeneratedPasswordDialog", true, 1); "KeyboardAccessory.GeneratedPasswordDialog", true, 1);
} }
TEST_F(PasswordGenerationControllerTest,
RelaysGenerationAcceptedToCorrectDriver) {
base::string16 test_password = ASCIIToUTF16("t3stp@ssw0rd");
InitializeGeneration(test_password);
controller()->OnGenerationRequested();
MockPasswordManagerDriver wrong_driver;
EXPECT_CALL(mock_manual_filling_controller_,
OnAutomaticGenerationStatusChanged(true));
controller()->OnAutomaticGenerationAvailable(GetTestGenerationUIData2(),
wrong_driver.AsWeakPtr());
EXPECT_CALL(*mock_password_manager_driver_,
GeneratedPasswordAccepted(test_password));
EXPECT_CALL(wrong_driver, GeneratedPasswordAccepted(_)).Times(0);
controller()->GeneratedPasswordAccepted(
test_password, mock_password_manager_driver_->AsWeakPtr());
}
...@@ -5,16 +5,22 @@ ...@@ -5,16 +5,22 @@
#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_GENERATION_DIALOG_VIEW_INTERFACE_H_ #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_GENERATION_DIALOG_VIEW_INTERFACE_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_GENERATION_DIALOG_VIEW_INTERFACE_H_ #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_GENERATION_DIALOG_VIEW_INTERFACE_H_
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
class PasswordGenerationController; class PasswordGenerationController;
namespace password_manager {
class PasswordManagerDriver;
} // namespace password_manager
class PasswordGenerationDialogViewInterface { class PasswordGenerationDialogViewInterface {
public: public:
virtual ~PasswordGenerationDialogViewInterface() = default; virtual ~PasswordGenerationDialogViewInterface() = default;
// Called to show the dialog. |password| is the generated password. // Called to show the dialog. |password| is the generated password.
virtual void Show(base::string16& password) = 0; virtual void Show(base::string16& password,
base::WeakPtr<password_manager::PasswordManagerDriver>
target_frame_driver) = 0;
private: private:
friend class PasswordGenerationControllerImpl; friend class PasswordGenerationControllerImpl;
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#include "base/android/jni_android.h" #include "base/android/jni_android.h"
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "chrome/browser/password_manager/password_generation_controller_impl.h" #include "chrome/browser/password_manager/password_generation_controller_impl.h"
#include "chrome/grit/chromium_strings.h" #include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "jni/PasswordGenerationDialogBridge_jni.h" #include "jni/PasswordGenerationDialogBridge_jni.h"
#include "ui/android/window_android.h" #include "ui/android/window_android.h"
...@@ -32,7 +34,11 @@ PasswordGenerationDialogViewAndroid::~PasswordGenerationDialogViewAndroid() { ...@@ -32,7 +34,11 @@ PasswordGenerationDialogViewAndroid::~PasswordGenerationDialogViewAndroid() {
base::android::AttachCurrentThread(), java_object_); base::android::AttachCurrentThread(), java_object_);
} }
void PasswordGenerationDialogViewAndroid::Show(base::string16& password) { void PasswordGenerationDialogViewAndroid::Show(
base::string16& password,
base::WeakPtr<password_manager::PasswordManagerDriver>
target_frame_driver) {
target_frame_driver_ = std::move(target_frame_driver);
JNIEnv* env = base::android::AttachCurrentThread(); JNIEnv* env = base::android::AttachCurrentThread();
base::string16 explanation_text = base::string16 explanation_text =
...@@ -48,7 +54,8 @@ void PasswordGenerationDialogViewAndroid::PasswordAccepted( ...@@ -48,7 +54,8 @@ void PasswordGenerationDialogViewAndroid::PasswordAccepted(
const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& password) { const base::android::JavaParamRef<jstring>& password) {
controller_->GeneratedPasswordAccepted( controller_->GeneratedPasswordAccepted(
base::android::ConvertJavaStringToUTF16(env, password)); base::android::ConvertJavaStringToUTF16(env, password),
std::move(target_frame_driver_));
} }
void PasswordGenerationDialogViewAndroid::PasswordRejected( void PasswordGenerationDialogViewAndroid::PasswordRejected(
......
...@@ -26,7 +26,9 @@ class PasswordGenerationDialogViewAndroid ...@@ -26,7 +26,9 @@ class PasswordGenerationDialogViewAndroid
~PasswordGenerationDialogViewAndroid() override; ~PasswordGenerationDialogViewAndroid() override;
// Called to show the dialog. |password| is the generated password. // Called to show the dialog. |password| is the generated password.
void Show(base::string16& password) override; void Show(base::string16& password,
base::WeakPtr<password_manager::PasswordManagerDriver>
target_frame_driver) override;
// Called from Java via JNI. // Called from Java via JNI.
void PasswordAccepted(JNIEnv* env, void PasswordAccepted(JNIEnv* env,
...@@ -44,6 +46,10 @@ class PasswordGenerationDialogViewAndroid ...@@ -44,6 +46,10 @@ class PasswordGenerationDialogViewAndroid
// The corresponding java object. // The corresponding java object.
base::android::ScopedJavaGlobalRef<jobject> java_object_; base::android::ScopedJavaGlobalRef<jobject> java_object_;
// The driver corresponding to the frame for which the generation request was
// made. Used to ensure that the accepted password message is sent back to the
// same frame.
base::WeakPtr<password_manager::PasswordManagerDriver> target_frame_driver_;
DISALLOW_COPY_AND_ASSIGN(PasswordGenerationDialogViewAndroid); DISALLOW_COPY_AND_ASSIGN(PasswordGenerationDialogViewAndroid);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment