summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvabr@chromium.org <vabr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-14 10:04:22 +0000
committervabr@chromium.org <vabr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-14 10:04:22 +0000
commit7e1ffcfe761f3ac9e0d34612e3c23f5a41229206 (patch)
tree1f85578782f6ad9e7c6097833846e40e3b3a3c4d
parent0c0a0365581443aefc3bb51e25fc5e37bd021772 (diff)
downloadchromium_src-7e1ffcfe761f3ac9e0d34612e3c23f5a41229206.zip
chromium_src-7e1ffcfe761f3ac9e0d34612e3c23f5a41229206.tar.gz
chromium_src-7e1ffcfe761f3ac9e0d34612e3c23f5a41229206.tar.bz2
Password manager internals page service 2: wiring it in
Start using the PasswordManagerInternalsService introduced in https://codereview.chromium.org/262583007/. This CL breaks the fragile direct link between PasswordManagerClient and the UI contoller of the internals page, inserting the service between. Design doc: https://docs.google.com/document/d/1ArDhTo0w-8tOPiTwqM1gG6ZGqODo8UTpXlJjjnCNK4s/edit?usp=sharing#heading=h.cqh4wuj8j4yl BUG=347927 Review URL: https://codereview.chromium.org/269513003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270372 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/password_manager/chrome_password_manager_client.cc64
-rw-r--r--chrome/browser/password_manager/chrome_password_manager_client.h11
-rw-r--r--chrome/browser/password_manager/chrome_password_manager_client_unittest.cc68
-rw-r--r--chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc98
-rw-r--r--chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h27
-rw-r--r--chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc23
-rw-r--r--components/password_manager/core/browser/log_router.cc10
-rw-r--r--components/password_manager/core/browser/log_router_unittest.cc61
-rw-r--r--components/password_manager/core/browser/password_manager_client.cc3
-rw-r--r--components/password_manager/core/browser/password_manager_client.h10
10 files changed, 208 insertions, 167 deletions
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index ecb7aa3..cddf254 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -21,8 +21,10 @@
#include "components/autofill/content/common/autofill_messages.h"
#include "components/autofill/core/browser/password_generator.h"
#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
#include "components/password_manager/core/browser/password_form_manager.h"
#include "components/password_manager/core/browser/password_manager.h"
+#include "components/password_manager/core/browser/password_manager_internals_service.h"
#include "components/password_manager/core/browser/password_manager_logger.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/common/password_manager_switches.h"
@@ -33,6 +35,9 @@
#include "chrome/browser/android/password_authentication_manager.h"
#endif // OS_ANDROID
+using password_manager::PasswordManagerInternalsService;
+using password_manager::PasswordManagerInternalsServiceFactory;
+
namespace {
bool IsTheHotNewBubbleUIEnabled() {
@@ -71,12 +76,23 @@ ChromePasswordManagerClient::ChromePasswordManagerClient(
content::WebContents* web_contents,
autofill::AutofillManagerDelegate* autofill_manager_delegate)
: content::WebContentsObserver(web_contents),
+ profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
driver_(web_contents, this, autofill_manager_delegate),
observer_(NULL),
weak_factory_(this),
- logger_(NULL) {}
+ can_use_log_router_(false) {
+ PasswordManagerInternalsService* service =
+ PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
+ if (service)
+ can_use_log_router_ = service->RegisterClient(this);
+}
-ChromePasswordManagerClient::~ChromePasswordManagerClient() {}
+ChromePasswordManagerClient::~ChromePasswordManagerClient() {
+ PasswordManagerInternalsService* service =
+ PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
+ if (service)
+ service->UnregisterClient(this);
+}
bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
return CommandLine::ForCurrentProcess()->HasSwitch(
@@ -136,17 +152,13 @@ void ChromePasswordManagerClient::AuthenticateAutofillAndFillForm(
#endif // OS_ANDROID
}
-Profile* ChromePasswordManagerClient::GetProfile() {
- return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
-}
-
void ChromePasswordManagerClient::HidePasswordGenerationPopup() {
if (popup_controller_)
popup_controller_->HideAndDestroy();
}
PrefService* ChromePasswordManagerClient::GetPrefs() {
- return GetProfile()->GetPrefs();
+ return profile_->GetPrefs();
}
password_manager::PasswordStore*
@@ -154,8 +166,8 @@ ChromePasswordManagerClient::GetPasswordStore() {
// Always use EXPLICIT_ACCESS as the password manager checks IsOffTheRecord
// itself when it shouldn't access the PasswordStore.
// TODO(gcasto): Is is safe to change this to Profile::IMPLICIT_ACCESS?
- return PasswordStoreFactory::GetForProfile(GetProfile(),
- Profile::EXPLICIT_ACCESS).get();
+ return PasswordStoreFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS)
+ .get();
}
password_manager::PasswordManagerDriver*
@@ -183,7 +195,7 @@ ChromePasswordManagerClient::GetProbabilityForExperiment(
bool ChromePasswordManagerClient::IsPasswordSyncEnabled() {
ProfileSyncService* sync_service =
- ProfileSyncServiceFactory::GetForProfile(GetProfile());
+ ProfileSyncServiceFactory::GetForProfile(profile_);
// Don't consider sync enabled if the user has a custom passphrase. See
// crbug.com/358998 for more details.
if (sync_service &&
@@ -195,29 +207,35 @@ bool ChromePasswordManagerClient::IsPasswordSyncEnabled() {
return false;
}
-void ChromePasswordManagerClient::SetLogger(
- password_manager::PasswordManagerLogger* logger) {
- // We should never be replacing one logger with a different one, because that
- // will leave the first without further updates, and the user likely confused.
- // TODO(vabr): For the reason above, before moving the internals page from
- // behind the flag, make sure to restrict the number of internals page
- // instances to 1 in normal profiles, and 0 in incognito.
- DCHECK(!logger || !logger_);
- logger_ = logger;
+void ChromePasswordManagerClient::OnLogRouterAvailabilityChanged(
+ bool router_can_be_used) {
+ if (can_use_log_router_ == router_can_be_used)
+ return;
+ can_use_log_router_ = router_can_be_used;
+
+ if (!web_contents())
+ return;
// Also inform the renderer process to start or stop logging.
web_contents()->GetRenderViewHost()->Send(new AutofillMsg_ChangeLoggingState(
- web_contents()->GetRenderViewHost()->GetRoutingID(), logger != NULL));
+ web_contents()->GetRenderViewHost()->GetRoutingID(),
+ can_use_log_router_));
}
void ChromePasswordManagerClient::LogSavePasswordProgress(
const std::string& text) {
- if (IsLoggingActive())
- logger_->LogSavePasswordProgress(text);
+ if (!IsLoggingActive())
+ return;
+ PasswordManagerInternalsService* service =
+ PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
+ if (service)
+ service->ProcessLog(text);
}
bool ChromePasswordManagerClient::IsLoggingActive() const {
- return logger_ != NULL;
+ // WebUI tabs do not need to log password saving progress. In particular, the
+ // internals page itself should not send any logs.
+ return can_use_log_router_ && !web_contents()->GetWebUI();
}
// static
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index f57fc3b..4fad507 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -53,8 +53,7 @@ class ChromePasswordManagerClient
virtual base::FieldTrial::Probability GetProbabilityForExperiment(
const std::string& experiment_name) OVERRIDE;
virtual bool IsPasswordSyncEnabled() OVERRIDE;
- virtual void SetLogger(password_manager::PasswordManagerLogger* logger)
- OVERRIDE;
+ virtual void OnLogRouterAvailabilityChanged(bool router_can_be_used) OVERRIDE;
virtual void LogSavePasswordProgress(const std::string& text) OVERRIDE;
virtual bool IsLoggingActive() const OVERRIDE;
@@ -107,7 +106,7 @@ class ChromePasswordManagerClient
void ShowPasswordEditingPopup(
const gfx::RectF& bounds, const autofill::PasswordForm& form);
- Profile* GetProfile();
+ Profile* const profile_;
password_manager::ContentPasswordManagerDriver driver_;
@@ -121,10 +120,8 @@ class ChromePasswordManagerClient
// Allows authentication callbacks to be destroyed when this client is gone.
base::WeakPtrFactory<ChromePasswordManagerClient> weak_factory_;
- // Points to an active logger instance to use for, e.g., reporting progress on
- // saving passwords. If there is no active logger (most of the time), the
- // pointer will be NULL.
- password_manager::PasswordManagerLogger* logger_;
+ // True if |this| is registered with some LogRouter which can accept logs.
+ bool can_use_log_router_;
DISALLOW_COPY_AND_ASSIGN(ChromePasswordManagerClient);
};
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 304975d..e96af45 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -8,7 +8,10 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/testing_profile.h"
#include "components/autofill/content/common/autofill_messages.h"
+#include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
+#include "components/password_manager/core/browser/password_manager_internals_service.h"
#include "components/password_manager/core/browser/password_manager_logger.h"
#include "components/password_manager/core/common/password_manager_switches.h"
#include "content/public/browser/browser_context.h"
@@ -24,11 +27,8 @@ namespace {
const char kTestText[] = "abcd1234";
-class MockPasswordManagerLogger
- : public password_manager::PasswordManagerLogger {
+class MockLogReceiver : public password_manager::PasswordManagerLogger {
public:
- MockPasswordManagerLogger() {}
-
MOCK_METHOD1(LogSavePasswordProgress, void(const std::string&));
};
@@ -36,6 +36,8 @@ class MockPasswordManagerLogger
class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness {
public:
+ ChromePasswordManagerClientTest();
+
virtual void SetUp() OVERRIDE;
protected:
@@ -46,13 +48,22 @@ class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness {
// returns false.
bool WasLoggingActivationMessageSent(bool* activation_flag);
- testing::StrictMock<MockPasswordManagerLogger> logger_;
+ password_manager::PasswordManagerInternalsService* service_;
+
+ testing::StrictMock<MockLogReceiver> receiver_;
};
+ChromePasswordManagerClientTest::ChromePasswordManagerClientTest()
+ : service_(NULL) {
+}
+
void ChromePasswordManagerClientTest::SetUp() {
ChromeRenderViewHostTestHarness::SetUp();
ChromePasswordManagerClient::CreateForWebContentsWithAutofillManagerDelegate(
web_contents(), NULL);
+ service_ = password_manager::PasswordManagerInternalsServiceFactory::
+ GetForBrowserContext(profile());
+ ASSERT_TRUE(service_);
}
ChromePasswordManagerClient* ChromePasswordManagerClientTest::GetClient() {
@@ -73,34 +84,39 @@ bool ChromePasswordManagerClientTest::WasLoggingActivationMessageSent(
return true;
}
-TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNoLogger) {
+TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNoReceiver) {
ChromePasswordManagerClient* client = GetClient();
- EXPECT_CALL(logger_, LogSavePasswordProgress(kTestText)).Times(0);
- // Before attaching the logger, no text should be passed.
+ EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
+ // Before attaching the receiver, no text should be passed.
client->LogSavePasswordProgress(kTestText);
EXPECT_FALSE(client->IsLoggingActive());
}
-TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressAttachLogger) {
+TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressAttachReceiver) {
ChromePasswordManagerClient* client = GetClient();
+ EXPECT_FALSE(client->IsLoggingActive());
// After attaching the logger, text should be passed.
- client->SetLogger(&logger_);
- EXPECT_CALL(logger_, LogSavePasswordProgress(kTestText)).Times(1);
- client->LogSavePasswordProgress(kTestText);
+ service_->RegisterReceiver(&receiver_);
EXPECT_TRUE(client->IsLoggingActive());
+ EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
+ client->LogSavePasswordProgress(kTestText);
+ service_->UnregisterReceiver(&receiver_);
+ EXPECT_FALSE(client->IsLoggingActive());
}
-TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressDetachLogger) {
+TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressDetachReceiver) {
ChromePasswordManagerClient* client = GetClient();
- client->SetLogger(&logger_);
+ service_->RegisterReceiver(&receiver_);
+ EXPECT_TRUE(client->IsLoggingActive());
+ service_->UnregisterReceiver(&receiver_);
+ EXPECT_FALSE(client->IsLoggingActive());
+
// After detaching the logger, no text should be passed.
- client->SetLogger(NULL);
- EXPECT_CALL(logger_, LogSavePasswordProgress(kTestText)).Times(0);
+ EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(0);
client->LogSavePasswordProgress(kTestText);
- EXPECT_FALSE(client->IsLoggingActive());
}
TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNotifyRenderer) {
@@ -110,11 +126,13 @@ TEST_F(ChromePasswordManagerClientTest, LogSavePasswordProgressNotifyRenderer) {
// Initially, the logging should be off, so no IPC messages.
EXPECT_FALSE(WasLoggingActivationMessageSent(&logging_active));
- client->SetLogger(&logger_);
+ service_->RegisterReceiver(&receiver_);
+ EXPECT_TRUE(client->IsLoggingActive());
EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
EXPECT_TRUE(logging_active);
- client->SetLogger(NULL);
+ service_->UnregisterReceiver(&receiver_);
+ EXPECT_FALSE(client->IsLoggingActive());
EXPECT_TRUE(WasLoggingActivationMessageSent(&logging_active));
EXPECT_FALSE(logging_active);
}
@@ -133,3 +151,15 @@ TEST_F(ChromePasswordManagerClientTest,
else
EXPECT_FALSE(GetClient()->IsAutomaticPasswordSavingEnabled());
}
+
+TEST_F(ChromePasswordManagerClientTest, LogToAReceiver) {
+ ChromePasswordManagerClient* client = GetClient();
+ service_->RegisterReceiver(&receiver_);
+ EXPECT_TRUE(client->IsLoggingActive());
+
+ EXPECT_CALL(receiver_, LogSavePasswordProgress(kTestText)).Times(1);
+ client->LogSavePasswordProgress(kTestText);
+
+ service_->UnregisterReceiver(&receiver_);
+ EXPECT_FALSE(client->IsLoggingActive());
+}
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
index 34d4611..9096347 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
@@ -7,26 +7,18 @@
#include <algorithm>
#include <set>
-#include "base/strings/string16.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
-#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/android/tab_model/tab_model.h"
-#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
-#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "chrome/common/url_constants.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
+#include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
+#include "components/password_manager/core/browser/password_manager_internals_service.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "grit/password_manager_internals_resources.h"
#include "net/base/escape.h"
-using content::BrowserContext;
-using content::WebContents;
+using password_manager::PasswordManagerInternalsService;
+using password_manager::PasswordManagerInternalsServiceFactory;
namespace {
@@ -42,92 +34,46 @@ content::WebUIDataSource* CreatePasswordManagerInternalsHTMLSource() {
return source;
}
-void InsertWebContentsIfProfileMatches(
- WebContents* web_contents,
- const Profile* profile_to_match,
- std::set<WebContents*>* set_of_web_contents) {
- if (static_cast<const BrowserContext*>(profile_to_match) ==
- web_contents->GetBrowserContext()) {
- set_of_web_contents->insert(web_contents);
- }
-}
-
} // namespace
PasswordManagerInternalsUI::PasswordManagerInternalsUI(content::WebUI* web_ui)
: WebUIController(web_ui),
WebContentsObserver(web_ui->GetWebContents()),
- did_stop_loading_(false) {
+ registered_with_logging_service_(false) {
// Set up the chrome://password-manager-internals/ source.
content::WebUIDataSource::Add(Profile::FromWebUI(web_ui),
CreatePasswordManagerInternalsHTMLSource());
- NotifyAllPasswordManagerClients(PAGE_OPENED);
}
PasswordManagerInternalsUI::~PasswordManagerInternalsUI() {
- NotifyAllPasswordManagerClients(PAGE_CLOSED);
+ if (!registered_with_logging_service_)
+ return;
+ PasswordManagerInternalsService* service =
+ PasswordManagerInternalsServiceFactory::GetForBrowserContext(
+ Profile::FromWebUI(web_ui()));
+ if (service)
+ service->UnregisterReceiver(this);
}
void PasswordManagerInternalsUI::DidStopLoading(
content::RenderViewHost* /* render_view_host */) {
- did_stop_loading_ = true;
- if (log_buffer_.empty())
- return;
- LogInternal(log_buffer_);
- log_buffer_.clear();
+ PasswordManagerInternalsService* service =
+ PasswordManagerInternalsServiceFactory::GetForBrowserContext(
+ Profile::FromWebUI(web_ui()));
+ if (service) {
+ registered_with_logging_service_ = true;
+ std::string past_logs(service->RegisterReceiver(this));
+ LogSavePasswordProgress(past_logs);
+ }
}
void PasswordManagerInternalsUI::LogSavePasswordProgress(
const std::string& text) {
- if (did_stop_loading_)
- LogInternal(text);
- else
- log_buffer_.append(text);
-}
-
-void PasswordManagerInternalsUI::LogInternal(const std::string& text) {
+ if (!registered_with_logging_service_)
+ return;
std::string no_quotes(text);
std::replace(no_quotes.begin(), no_quotes.end(), '"', ' ');
base::StringValue text_string_value(net::EscapeForHTML(no_quotes));
web_ui()->CallJavascriptFunction("addSavePasswordProgressLog",
text_string_value);
}
-
-void PasswordManagerInternalsUI::NotifyAllPasswordManagerClients(
- ClientNotificationType notification_type) {
- // First, find all the WebContents objects of the current profile.
- Profile* current_profile = Profile::FromWebUI(web_ui());
- std::set<WebContents*> profile_web_contents;
-#if defined(OS_ANDROID)
- for (TabModelList::const_iterator iter = TabModelList::begin();
- iter != TabModelList::end();
- ++iter) {
- TabModel* model = *iter;
- for (int i = 0; i < model->GetTabCount(); ++i) {
- InsertWebContentsIfProfileMatches(
- model->GetWebContentsAt(i), current_profile, &profile_web_contents);
- }
- }
-#else
- for (TabContentsIterator iter; !iter.done(); iter.Next()) {
- InsertWebContentsIfProfileMatches(
- *iter, current_profile, &profile_web_contents);
- }
-#endif
-
- // Now get the corresponding PasswordManagerClients, and attach/detach |this|.
- for (std::set<WebContents*>::iterator it = profile_web_contents.begin();
- it != profile_web_contents.end();
- ++it) {
- ChromePasswordManagerClient* client =
- ChromePasswordManagerClient::FromWebContents(*it);
- switch (notification_type) {
- case PAGE_OPENED:
- client->SetLogger(this);
- break;
- case PAGE_CLOSED:
- client->SetLogger(NULL);
- break;
- }
- }
-}
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h
index c73486a..3265301 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h
@@ -25,30 +25,9 @@ class PasswordManagerInternalsUI
virtual void LogSavePasswordProgress(const std::string& text) OVERRIDE;
private:
- // These types describe which kinds of notifications
- // PasswordManagerInternalsUI can send to PasswordManagerClient.
- enum ClientNotificationType {
- PAGE_OPENED, // Send when the page gets opened.
- PAGE_CLOSED // Send when the page gets closed.
- };
-
- // This acts on all PasswordManagerClient instances of the current profile
- // based on |notification_type|:
- // PAGE_OPENED -- |this| is set as clients' PasswordManagerLogger
- // PAGE_CLOSED -- PasswordManagerLogger is reset for clients
- void NotifyAllPasswordManagerClients(
- ClientNotificationType notification_type);
-
- // Helper used by LogSavePasswordProgress, actually sends |text| to the
- // internals page.
- void LogInternal(const std::string& text);
-
- // Whether the observed WebContents did stop loading.
- bool did_stop_loading_;
-
- // Stores the logs here until |did_stop_loading_| becomes true. At that point
- // all stored logs are displayed and any new are displayed directly.
- std::string log_buffer_;
+ // Whether |this| registered as a log receiver with the
+ // PasswordManagerInternalsService.
+ bool registered_with_logging_service_;
DISALLOW_COPY_AND_ASSIGN(PasswordManagerInternalsUI);
};
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc
index 817866b..16697a2 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui_browsertest.cc
@@ -3,12 +3,15 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/base/web_ui_browsertest.h"
+#include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
+#include "components/password_manager/core/browser/password_manager_internals_service.h"
#include "components/password_manager/core/common/password_manager_switches.h"
#include "content/public/browser/web_contents.h"
@@ -27,10 +30,6 @@ class PasswordManagerInternalsWebUIBrowserTest : public WebUIBrowserTest {
// the corresponding UI controller to |controller_|.
void OpenNewTabWithTheInternalsPage();
- PasswordManagerInternalsUI* controller() {
- return controller_;
- };
-
private:
PasswordManagerInternalsUI* controller_;
};
@@ -75,7 +74,11 @@ PasswordManagerInternalsWebUIBrowserTest::OpenNewTabWithTheInternalsPage() {
IN_PROC_BROWSER_TEST_F(PasswordManagerInternalsWebUIBrowserTest,
LogSavePasswordProgress) {
- controller()->LogSavePasswordProgress("<script> text for testing");
+ password_manager::PasswordManagerInternalsService* service =
+ password_manager::PasswordManagerInternalsServiceFactory::
+ GetForBrowserContext(browser()->profile());
+ ASSERT_TRUE(service);
+ service->ProcessLog("<script> text for testing");
ASSERT_TRUE(RunJavascriptTest("testLogText"));
}
@@ -84,12 +87,14 @@ IN_PROC_BROWSER_TEST_F(PasswordManagerInternalsWebUIBrowserTest,
// logs created before the second tab was opened, and also that the second tab
// waits with displaying until the internals page is ready (trying to display
// the old logs just on construction time would fail).
-// TODO(vabr): Disabled until multiple tabs with the internals page can exist
-// without crashing.
IN_PROC_BROWSER_TEST_F(PasswordManagerInternalsWebUIBrowserTest,
- DISABLED_LogSavePasswordProgress_MultipleTabsIdentical) {
+ LogSavePasswordProgress_MultipleTabsIdentical) {
// First, open one tab with the internals page, and log something.
- controller()->LogSavePasswordProgress("<script> text for testing");
+ password_manager::PasswordManagerInternalsService* service =
+ password_manager::PasswordManagerInternalsServiceFactory::
+ GetForBrowserContext(browser()->profile());
+ ASSERT_TRUE(service);
+ service->ProcessLog("<script> text for testing");
ASSERT_TRUE(RunJavascriptTest("testLogText"));
// Now open a second tab with the internals page, but do not log anything.
OpenNewTabWithTheInternalsPage();
diff --git a/components/password_manager/core/browser/log_router.cc b/components/password_manager/core/browser/log_router.cc
index c8719a8..7aee715 100644
--- a/components/password_manager/core/browser/log_router.cc
+++ b/components/password_manager/core/browser/log_router.cc
@@ -40,8 +40,10 @@ std::string LogRouter::RegisterReceiver(PasswordManagerLogger* receiver) {
DCHECK(receiver);
DCHECK(accumulated_logs_.empty() || receivers_.might_have_observers());
- // TODO(vabr): Once the clients provide API for that, notify them if the
- // number of receivers went from 0 to 1.
+ if (!receivers_.might_have_observers()) {
+ FOR_EACH_OBSERVER(
+ PasswordManagerClient, clients_, OnLogRouterAvailabilityChanged(true));
+ }
receivers_.AddObserver(receiver);
return accumulated_logs_;
}
@@ -51,8 +53,8 @@ void LogRouter::UnregisterReceiver(PasswordManagerLogger* receiver) {
receivers_.RemoveObserver(receiver);
if (!receivers_.might_have_observers()) {
accumulated_logs_.clear();
- // TODO(vabr): Once the clients provide API for that, notify them that the
- // number of receivers went from 1 to 0.
+ FOR_EACH_OBSERVER(
+ PasswordManagerClient, clients_, OnLogRouterAvailabilityChanged(false));
}
}
diff --git a/components/password_manager/core/browser/log_router_unittest.cc b/components/password_manager/core/browser/log_router_unittest.cc
index b890998..6c02dae 100644
--- a/components/password_manager/core/browser/log_router_unittest.cc
+++ b/components/password_manager/core/browser/log_router_unittest.cc
@@ -24,12 +24,18 @@ class MockLogReceiver : public PasswordManagerLogger {
MOCK_METHOD1(LogSavePasswordProgress, void(const std::string&));
};
+class MockClient : public StubPasswordManagerClient {
+ public:
+ MOCK_METHOD1(OnLogRouterAvailabilityChanged, void(bool));
+};
+
} // namespace
class LogRouterTest : public testing::Test {
protected:
testing::StrictMock<MockLogReceiver> receiver_;
testing::StrictMock<MockLogReceiver> receiver2_;
+ testing::StrictMock<MockClient> client_;
};
TEST_F(LogRouterTest, ProcessLog_NoReceiver) {
@@ -93,4 +99,59 @@ TEST_F(LogRouterTest, ProcessLog_TwoReceiversNoUpdateAfterUnregistering) {
router.UnregisterReceiver(&receiver2_);
}
+TEST_F(LogRouterTest, RegisterClient_NoReceivers) {
+ LogRouter router;
+ EXPECT_FALSE(router.RegisterClient(&client_));
+ router.UnregisterClient(&client_);
+}
+
+TEST_F(LogRouterTest, RegisterClient_OneReceiverBeforeClient) {
+ LogRouter router;
+ // First register a receiver.
+ EXPECT_EQ(std::string(), router.RegisterReceiver(&receiver_));
+ // The client should be told the LogRouter has some receivers.
+ EXPECT_TRUE(router.RegisterClient(&client_));
+ // Now unregister the reciever. The client should be told the LogRouter has no
+ // receivers.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(false)).Times(1);
+ router.UnregisterReceiver(&receiver_);
+ router.UnregisterClient(&client_);
+}
+
+TEST_F(LogRouterTest, RegisterClient_OneClientBeforeReceiver) {
+ LogRouter router;
+ // First register a client; the client should be told the LogRouter has no
+ // receivers.
+ EXPECT_FALSE(router.RegisterClient(&client_));
+ // Now register the receiver. The client should be notified.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(true)).Times(1);
+ EXPECT_EQ(std::string(), router.RegisterReceiver(&receiver_));
+ // Now unregister the client.
+ router.UnregisterClient(&client_);
+ // Now unregister the reciever. The client should not hear about it.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(_)).Times(0);
+ router.UnregisterReceiver(&receiver_);
+}
+
+TEST_F(LogRouterTest, RegisterClient_OneClientTwoReceivers) {
+ LogRouter router;
+ // First register a client; the client should be told the LogRouter has no
+ // receivers.
+ EXPECT_FALSE(router.RegisterClient(&client_));
+ // Now register the 1st receiver. The client should be notified.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(true)).Times(1);
+ EXPECT_EQ(std::string(), router.RegisterReceiver(&receiver_));
+ // Now register the 2nd receiver. The client should not be notified.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(true)).Times(0);
+ EXPECT_EQ(std::string(), router.RegisterReceiver(&receiver2_));
+ // Now unregister the 1st reciever. The client should not hear about it.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(false)).Times(0);
+ router.UnregisterReceiver(&receiver_);
+ // Now unregister the 2nd reciever. The client should hear about it.
+ EXPECT_CALL(client_, OnLogRouterAvailabilityChanged(false)).Times(1);
+ router.UnregisterReceiver(&receiver2_);
+ // Now unregister the client.
+ router.UnregisterClient(&client_);
+}
+
} // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc
index 1ff2f50..ddadd2d 100644
--- a/components/password_manager/core/browser/password_manager_client.cc
+++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -18,7 +18,8 @@ PasswordManagerClient::GetProbabilityForExperiment(
bool PasswordManagerClient::IsPasswordSyncEnabled() { return false; }
-void PasswordManagerClient::SetLogger(PasswordManagerLogger* logger) {
+void PasswordManagerClient::OnLogRouterAvailabilityChanged(
+ bool router_can_be_used) {
}
void PasswordManagerClient::LogSavePasswordProgress(const std::string& text) {
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index 3793865..e1c765e 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -16,7 +16,6 @@ namespace password_manager {
class PasswordFormManager;
class PasswordManagerDriver;
class PasswordStore;
-class PasswordManagerLogger;
// An abstraction of operations that depend on the embedders (e.g. Chrome)
// environment.
@@ -73,10 +72,13 @@ class PasswordManagerClient {
// implementation returns false.
virtual bool IsPasswordSyncEnabled();
- // Attach or detach (setting NULL) a logger for this client.
- virtual void SetLogger(PasswordManagerLogger* logger);
+ // Only for clients which registered with a LogRouter: If called with
+ // |router_can_be_used| set to false, the client may no longer use the
+ // LogRouter. If |router_can_be_used| is true, the LogRouter can be used after
+ // the return from OnLogRouterAvailabilityChanged.
+ virtual void OnLogRouterAvailabilityChanged(bool router_can_be_used);
- // Send |text| to the logger.
+ // Forward |text| for display to the LogRouter (if registered with one).
virtual void LogSavePasswordProgress(const std::string& text);
// Returns true if logs recorded via LogSavePasswordProgress will be