Commit c6ac8870 authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

Notify chrome://settings about changes to password account storage opt-in

This is a followup to https://crrev.com/c/2039190 which added an API
to query the opt-in state.

Actually using any of the new APIs is still left for future CLs.

Bug: 1049141
Change-Id: I3bda91ad80286a070c47465ecbb7ad5677db1126
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2039450
Commit-Queue: Marc Treib <treib@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarMohamed Amir Yosef <mamir@chromium.org>
Cr-Commit-Position: refs/heads/master@{#740284}
parent 56b99d4e
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
#include "chrome/common/extensions/api/passwords_private.h" #include "chrome/common/extensions/api/passwords_private.h"
...@@ -100,6 +101,14 @@ PasswordsPrivateDelegateImpl::PasswordsPrivateDelegateImpl(Profile* profile) ...@@ -100,6 +101,14 @@ PasswordsPrivateDelegateImpl::PasswordsPrivateDelegateImpl(Profile* profile)
password_access_authenticator_( password_access_authenticator_(
base::BindRepeating(&PasswordsPrivateDelegateImpl::OsReauthCall, base::BindRepeating(&PasswordsPrivateDelegateImpl::OsReauthCall,
base::Unretained(this))), base::Unretained(this))),
password_account_storage_opt_in_watcher_(
std::make_unique<
password_manager::PasswordAccountStorageOptInWatcher>(
IdentityManagerFactory::GetForProfile(profile_),
profile_->GetPrefs(),
base::BindRepeating(&PasswordsPrivateDelegateImpl::
OnAccountStorageOptInStateChanged,
base::Unretained(this)))),
current_entries_initialized_(false), current_entries_initialized_(false),
current_exceptions_initialized_(false), current_exceptions_initialized_(false),
is_initialized_(false), is_initialized_(false),
...@@ -363,9 +372,18 @@ void PasswordsPrivateDelegateImpl::OnPasswordsExportProgress( ...@@ -363,9 +372,18 @@ void PasswordsPrivateDelegateImpl::OnPasswordsExportProgress(
} }
} }
void PasswordsPrivateDelegateImpl::OnAccountStorageOptInStateChanged() {
PasswordsPrivateEventRouter* router =
PasswordsPrivateEventRouterFactory::GetForProfile(profile_);
if (router) {
router->OnAccountStorageOptInStateChanged(IsOptedInForAccountStorage());
}
}
void PasswordsPrivateDelegateImpl::Shutdown() { void PasswordsPrivateDelegateImpl::Shutdown() {
password_manager_presenter_.reset(); password_account_storage_opt_in_watcher_.reset();
password_manager_porter_.reset(); password_manager_porter_.reset();
password_manager_presenter_.reset();
} }
SortKeyIdGenerator& SortKeyIdGenerator&
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "chrome/common/extensions/api/passwords_private.h" #include "chrome/common/extensions/api/passwords_private.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "components/password_manager/core/browser/password_access_authenticator.h" #include "components/password_manager/core/browser/password_access_authenticator.h"
#include "components/password_manager/core/browser/password_account_storage_opt_in_watcher.h"
#include "components/password_manager/core/browser/reauth_purpose.h" #include "components/password_manager/core/browser/reauth_purpose.h"
#include "components/password_manager/core/browser/ui/export_progress_status.h" #include "components/password_manager/core/browser/ui/export_progress_status.h"
#include "extensions/browser/extension_function.h" #include "extensions/browser/extension_function.h"
...@@ -73,10 +74,6 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate, ...@@ -73,10 +74,6 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate,
const std::vector<std::unique_ptr<autofill::PasswordForm>>& const std::vector<std::unique_ptr<autofill::PasswordForm>>&
password_exception_list) override; password_exception_list) override;
// Callback for when the password list has been written to the destination.
void OnPasswordsExportProgress(password_manager::ExportProgressStatus status,
const std::string& folder_name);
// KeyedService overrides: // KeyedService overrides:
void Shutdown() override; void Shutdown() override;
...@@ -109,6 +106,12 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate, ...@@ -109,6 +106,12 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate,
void RemovePasswordExceptionInternal(int id); void RemovePasswordExceptionInternal(int id);
void UndoRemoveSavedPasswordOrExceptionInternal(); void UndoRemoveSavedPasswordOrExceptionInternal();
// Callback for when the password list has been written to the destination.
void OnPasswordsExportProgress(password_manager::ExportProgressStatus status,
const std::string& folder_name);
void OnAccountStorageOptInStateChanged();
// Triggers an OS-dependent UI to present OS account login challenge and // Triggers an OS-dependent UI to present OS account login challenge and
// returns true if the user passed that challenge. // returns true if the user passed that challenge.
bool OsReauthCall(password_manager::ReauthPurpose purpose); bool OsReauthCall(password_manager::ReauthPurpose purpose);
...@@ -124,6 +127,9 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate, ...@@ -124,6 +127,9 @@ class PasswordsPrivateDelegateImpl : public PasswordsPrivateDelegate,
password_manager::PasswordAccessAuthenticator password_access_authenticator_; password_manager::PasswordAccessAuthenticator password_access_authenticator_;
std::unique_ptr<password_manager::PasswordAccountStorageOptInWatcher>
password_account_storage_opt_in_watcher_;
// The current list of entries/exceptions. Cached here so that when new // The current list of entries/exceptions. Cached here so that when new
// observers are added, this delegate can send the current lists without // observers are added, this delegate can send the current lists without
// having to request them from |password_manager_presenter_| again. // having to request them from |password_manager_presenter_| again.
......
...@@ -86,6 +86,16 @@ void PasswordsPrivateEventRouter::OnPasswordsExportProgress( ...@@ -86,6 +86,16 @@ void PasswordsPrivateEventRouter::OnPasswordsExportProgress(
event_router_->BroadcastEvent(std::move(extension_event)); event_router_->BroadcastEvent(std::move(extension_event));
} }
void PasswordsPrivateEventRouter::OnAccountStorageOptInStateChanged(
bool opted_in) {
auto extension_event = std::make_unique<Event>(
events::PASSWORDS_PRIVATE_ON_ACCOUNT_STORAGE_OPT_IN_STATE_CHANGED,
api::passwords_private::OnAccountStorageOptInStateChanged::kEventName,
api::passwords_private::OnAccountStorageOptInStateChanged::Create(
opted_in));
event_router_->BroadcastEvent(std::move(extension_event));
}
PasswordsPrivateEventRouter* PasswordsPrivateEventRouter::Create( PasswordsPrivateEventRouter* PasswordsPrivateEventRouter::Create(
content::BrowserContext* context) { content::BrowserContext* context) {
return new PasswordsPrivateEventRouter(context); return new PasswordsPrivateEventRouter(context);
......
...@@ -53,6 +53,10 @@ class PasswordsPrivateEventRouter : public KeyedService { ...@@ -53,6 +53,10 @@ class PasswordsPrivateEventRouter : public KeyedService {
api::passwords_private::ExportProgressStatus status, api::passwords_private::ExportProgressStatus status,
const std::string& folder_name); const std::string& folder_name);
// Notifies listeners about a (possible) change to the opt-in state for the
// account-scoped password storage.
void OnAccountStorageOptInStateChanged(bool opted_in);
protected: protected:
explicit PasswordsPrivateEventRouter(content::BrowserContext* context); explicit PasswordsPrivateEventRouter(content::BrowserContext* context);
......
...@@ -130,6 +130,18 @@ class PasswordManagerProxy { ...@@ -130,6 +130,18 @@ class PasswordManagerProxy {
cancelExportPasswords() {} cancelExportPasswords() {}
/**
* Add an observer to the account storage opt-in state.
* @param {function(boolean):void} listener
*/
addAccountStorageOptInStateListener(listener) {}
/**
* Remove an observer to the account storage opt-in state.
* @param {function(boolean):void} listener
*/
removeAccountStorageOptInStateListener(listener) {}
/** /**
* Requests the account-storage opt-in state of the current user. * Requests the account-storage opt-in state of the current user.
* @return {!Promise<(boolean)>} A promise that resolves to the opt-in state. * @return {!Promise<(boolean)>} A promise that resolves to the opt-in state.
...@@ -250,6 +262,18 @@ class PasswordManagerImpl { ...@@ -250,6 +262,18 @@ class PasswordManagerImpl {
chrome.passwordsPrivate.cancelExportPasswords(); chrome.passwordsPrivate.cancelExportPasswords();
} }
/** @override */
addAccountStorageOptInStateListener(listener) {
chrome.passwordsPrivate.onAccountStorageOptInStateChanged.addListener(
listener);
}
/** @override */
removeAccountStorageOptInStateListener(listener) {
chrome.passwordsPrivate.onAccountStorageOptInStateChanged.removeListener(
listener);
}
/** @override */ /** @override */
isOptedInForAccountStorage() { isOptedInForAccountStorage() {
return new Promise(resolve => { return new Promise(resolve => {
......
...@@ -161,5 +161,9 @@ namespace passwordsPrivate { ...@@ -161,5 +161,9 @@ namespace passwordsPrivate {
// Fired when the status of the export has changed. // Fired when the status of the export has changed.
// |status|: The progress status and an optional UI message. // |status|: The progress status and an optional UI message.
static void onPasswordsFileExportProgress(PasswordExportProgress status); static void onPasswordsFileExportProgress(PasswordExportProgress status);
// Fired when the opt-in state for the account-scoped storage has changed.
// |optedIn|: The new opt-in state.
static void onAccountStorageOptInStateChanged(boolean optedIn);
}; };
}; };
...@@ -129,6 +129,8 @@ jumbo_static_library("browser") { ...@@ -129,6 +129,8 @@ jumbo_static_library("browser") {
"origin_credential_store.h", "origin_credential_store.h",
"password_access_authenticator.cc", "password_access_authenticator.cc",
"password_access_authenticator.h", "password_access_authenticator.h",
"password_account_storage_opt_in_watcher.cc",
"password_account_storage_opt_in_watcher.h",
"password_autofill_manager.cc", "password_autofill_manager.cc",
"password_autofill_manager.h", "password_autofill_manager.h",
"password_bubble_experiment.cc", "password_bubble_experiment.cc",
......
// 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/password_manager/core/browser/password_account_storage_opt_in_watcher.h"
#include <utility>
#include "base/callback.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
namespace password_manager {
PasswordAccountStorageOptInWatcher::PasswordAccountStorageOptInWatcher(
signin::IdentityManager* identity_manager,
PrefService* pref_service,
base::RepeatingClosure change_callback)
: identity_manager_(identity_manager),
change_callback_(std::move(change_callback)) {
// The opt-in state is per-account, so it can change whenever the state of the
// signed-in account (aka unconsented primary account) changes.
identity_manager_->AddObserver(this);
// The opt-in state is stored in a pref, so changes to the pref might indicate
// a change to the opt-in state.
pref_change_registrar_.Init(pref_service);
pref_change_registrar_.Add(
password_manager::prefs::kAccountStoragePerAccountSettings,
change_callback_);
}
PasswordAccountStorageOptInWatcher::~PasswordAccountStorageOptInWatcher() {
identity_manager_->RemoveObserver(this);
}
void PasswordAccountStorageOptInWatcher::OnUnconsentedPrimaryAccountChanged(
const CoreAccountInfo& unconsented_primary_account_info) {
change_callback_.Run();
}
} // namespace password_manager
// 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.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_ACCOUNT_STORAGE_OPT_IN_WATCHER_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_ACCOUNT_STORAGE_OPT_IN_WATCHER_H_
#include "base/callback_forward.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/signin/public/identity_manager/identity_manager.h"
class PrefService;
namespace password_manager {
// Helper class to watch for changes to the opt-in state for the account-scoped
// password storage (see password_manager_util::IsOptedInForAccountStorage()).
class PasswordAccountStorageOptInWatcher
: public signin::IdentityManager::Observer {
public:
// |identity_manager| and |pref_service| must not be null and must outlive
// this object.
// |change_callback| will be invoked whenever the state of
// password_manager_util::IsOptedInForAccountStorage() might have changed.
PasswordAccountStorageOptInWatcher(signin::IdentityManager* identity_manager,
PrefService* pref_service,
base::RepeatingClosure change_callback);
~PasswordAccountStorageOptInWatcher() override;
// identity::IdentityManager::Observer:
void OnUnconsentedPrimaryAccountChanged(
const CoreAccountInfo& unconsented_primary_account_info) override;
private:
signin::IdentityManager* const identity_manager_;
base::RepeatingClosure change_callback_;
PrefChangeRegistrar pref_change_registrar_;
};
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_ACCOUNT_STORAGE_OPT_IN_WATCHER_H_
...@@ -470,6 +470,7 @@ enum HistogramValue { ...@@ -470,6 +470,7 @@ enum HistogramValue {
AUTOFILL_ASSISTANT_PRIVATE_ON_ACTIONS_CHANGED = 448, AUTOFILL_ASSISTANT_PRIVATE_ON_ACTIONS_CHANGED = 448,
AUTOFILL_ASSISTANT_PRIVATE_ON_STATUS_MESSAGE_CHANGED = 449, AUTOFILL_ASSISTANT_PRIVATE_ON_STATUS_MESSAGE_CHANGED = 449,
BLUETOOTH_PRIVATE_ON_DEVICE_ADDRESS_CHANGED = 450, BLUETOOTH_PRIVATE_ON_DEVICE_ADDRESS_CHANGED = 450,
PASSWORDS_PRIVATE_ON_ACCOUNT_STORAGE_OPT_IN_STATE_CHANGED = 451,
// Last entry: Add new entries above, then run: // Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py // python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY ENUM_BOUNDARY
......
...@@ -178,3 +178,9 @@ chrome.passwordsPrivate.onPasswordExceptionsListChanged; ...@@ -178,3 +178,9 @@ chrome.passwordsPrivate.onPasswordExceptionsListChanged;
* @type {!ChromeEvent} * @type {!ChromeEvent}
*/ */
chrome.passwordsPrivate.onPasswordsFileExportProgress; chrome.passwordsPrivate.onPasswordsFileExportProgress;
/**
* Fired when the opt-in state for the account-scoped storage has changed.
* @type {!ChromeEvent}
*/
chrome.passwordsPrivate.onAccountStorageOptInStateChanged;
...@@ -20710,6 +20710,8 @@ to ensure that the crash string is shown properly on the user-facing crash UI. ...@@ -20710,6 +20710,8 @@ to ensure that the crash string is shown properly on the user-facing crash UI.
<int value="449" <int value="449"
label="AUTOFILL_ASSISTANT_PRIVATE_ON_STATUS_MESSAGE_CHANGED"/> label="AUTOFILL_ASSISTANT_PRIVATE_ON_STATUS_MESSAGE_CHANGED"/>
<int value="450" label="BLUETOOTH_PRIVATE_ON_DEVICE_ADDRESS_CHANGED"/> <int value="450" label="BLUETOOTH_PRIVATE_ON_DEVICE_ADDRESS_CHANGED"/>
<int value="451"
label="PASSWORDS_PRIVATE_ON_ACCOUNT_STORAGE_OPT_IN_STATE_CHANGED"/>
</enum> </enum>
<enum name="ExtensionFileWriteResult"> <enum name="ExtensionFileWriteResult">
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