Commit 533bdefc authored by Mike Dougherty's avatar Mike Dougherty Committed by Commit Bot

[iOS] Add breadcrumbs for inforbars::InfoBarManager::Observer

In order to support testing of these breadcrumbs, extend FakeInfobarIOS
to be created with a custom delegate FakeInfobarDelegate.
FakeInfobarDelegate is also extended to support initialization with a
custom infobar identifier.

Bug: 1059110
Change-Id: Ib936f6103f2289e97c72be9ab9935697ebd66cdf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2095213
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#750390}
parent ad0c0a01
...@@ -16,10 +16,12 @@ source_set("feature_flags") { ...@@ -16,10 +16,12 @@ source_set("feature_flags") {
source_set("breadcrumbs") { source_set("breadcrumbs") {
deps = [ deps = [
"//base", "//base",
"//components/infobars/core",
"//components/keyed_service/core", "//components/keyed_service/core",
"//components/keyed_service/ios", "//components/keyed_service/ios",
"//ios/chrome/browser:chrome_url_constants", "//ios/chrome/browser:chrome_url_constants",
"//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state",
"//ios/chrome/browser/infobars",
"//ios/chrome/browser/main:public", "//ios/chrome/browser/main:public",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
"//ios/net", "//ios/net",
...@@ -79,8 +81,11 @@ source_set("unit_tests") { ...@@ -79,8 +81,11 @@ source_set("unit_tests") {
"//base/test:test_support", "//base/test:test_support",
"//ios/chrome/browser:chrome_url_constants", "//ios/chrome/browser:chrome_url_constants",
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/infobars",
"//ios/chrome/browser/infobars/test",
"//ios/chrome/browser/main:test_support", "//ios/chrome/browser/main:test_support",
"//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/commands",
"//ios/chrome/browser/ui/infobars/test",
"//ios/chrome/browser/web:test_support", "//ios/chrome/browser/web:test_support",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
"//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/browser/web_state_list:test_support",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/main/test_browser.h"
#import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
#include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
...@@ -59,6 +60,7 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, LogEvent) { ...@@ -59,6 +60,7 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, LogEvent) {
web::WebState::CreateParams createParams(browser_state_.get()); web::WebState::CreateParams createParams(browser_state_.get());
std::unique_ptr<web::WebState> web_state = std::unique_ptr<web::WebState> web_state =
web::WebState::Create(createParams); web::WebState::Create(createParams);
InfoBarManagerImpl::CreateForWebState(web_state.get());
BreadcrumbManagerTabHelper::CreateForWebState(web_state.get()); BreadcrumbManagerTabHelper::CreateForWebState(web_state.get());
browser->GetWebStateList()->InsertWebState( browser->GetWebStateList()->InsertWebState(
/*index=*/0, std::move(web_state), /*index=*/0, std::move(web_state),
...@@ -83,6 +85,7 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) { ...@@ -83,6 +85,7 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) {
web::WebState::CreateParams createParams(browser_state_.get()); web::WebState::CreateParams createParams(browser_state_.get());
std::unique_ptr<web::WebState> web_state = std::unique_ptr<web::WebState> web_state =
web::WebState::Create(createParams); web::WebState::Create(createParams);
InfoBarManagerImpl::CreateForWebState(web_state.get());
BreadcrumbManagerTabHelper::CreateForWebState(web_state.get()); BreadcrumbManagerTabHelper::CreateForWebState(web_state.get());
browser->GetWebStateList()->InsertWebState( browser->GetWebStateList()->InsertWebState(
/*index=*/0, std::move(web_state), /*index=*/0, std::move(web_state),
...@@ -97,6 +100,7 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) { ...@@ -97,6 +100,7 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) {
// Insert WebState into |browser2|. // Insert WebState into |browser2|.
std::unique_ptr<web::WebState> web_state2 = std::unique_ptr<web::WebState> web_state2 =
web::WebState::Create(createParams); web::WebState::Create(createParams);
InfoBarManagerImpl::CreateForWebState(web_state2.get());
BreadcrumbManagerTabHelper::CreateForWebState(web_state2.get()); BreadcrumbManagerTabHelper::CreateForWebState(web_state2.get());
browser2->GetWebStateList()->InsertWebState( browser2->GetWebStateList()->InsertWebState(
/*index=*/0, std::move(web_state2), /*index=*/0, std::move(web_state2),
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_ #ifndef IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_
#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_ #define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_TAB_HELPER_H_
#include "base/scoped_observer.h"
#include "components/infobars/core/infobar_manager.h"
#include "ios/web/public/web_state_observer.h" #include "ios/web/public/web_state_observer.h"
#import "ios/web/public/web_state_user_data.h" #import "ios/web/public/web_state_user_data.h"
...@@ -25,6 +27,18 @@ extern const char kBreadcrumbPageLoaded[]; ...@@ -25,6 +27,18 @@ extern const char kBreadcrumbPageLoaded[];
// (see WebStateObserver::DidChangeVisibleSecurityState). // (see WebStateObserver::DidChangeVisibleSecurityState).
extern const char kBreadcrumbDidChangeVisibleSecurityState[]; extern const char kBreadcrumbDidChangeVisibleSecurityState[];
// Name of OnInfoBarAdded event
// (see infobars::InfoBarManager::Observer::OnInfoBarAdded).
extern const char kBreadcrumbInfobarAdded[];
// Name of OnInfoBarRemoved event
// (see infobars::InfoBarManager::Observer::OnInfoBarRemoved).
extern const char kBreadcrumbInfobarRemoved[];
// Name of OnInfoBarReplaced event
// (see infobars::InfoBarManager::Observer::OnInfoBarReplaced).
extern const char kBreadcrumbInfobarReplaced[];
// Constants below represent metadata for breadcrumb events. // Constants below represent metadata for breadcrumb events.
// Appended to |kBreadcrumbDidChangeVisibleSecurityState| event if page has bad // Appended to |kBreadcrumbDidChangeVisibleSecurityState| event if page has bad
...@@ -35,6 +49,9 @@ extern const char kBreadcrumbAuthenticationBroken[]; ...@@ -35,6 +49,9 @@ extern const char kBreadcrumbAuthenticationBroken[];
// navigation is a download. // navigation is a download.
extern const char kBreadcrumbDownload[]; extern const char kBreadcrumbDownload[];
// Appended to |kBreadcrumbInfobarRemoved| if infobar removal is not animated.
extern const char kBreadcrumbInfobarNotAnimated[];
// Appended to |kBreadcrumbDidChangeVisibleSecurityState| event if page has // Appended to |kBreadcrumbDidChangeVisibleSecurityState| event if page has
// passive mixed content (f.e. an http served image on https served page). // passive mixed content (f.e. an http served image on https served page).
extern const char kBreadcrumbMixedContent[]; extern const char kBreadcrumbMixedContent[];
...@@ -57,10 +74,10 @@ extern const char kBreadcrumbRendererInitiatedByScript[]; ...@@ -57,10 +74,10 @@ extern const char kBreadcrumbRendererInitiatedByScript[];
// widow.open with user gesture). // widow.open with user gesture).
extern const char kBreadcrumbRendererInitiatedByUser[]; extern const char kBreadcrumbRendererInitiatedByUser[];
// Handles logging of Breadcrumb events associated with |web_state_| based on // Handles logging of Breadcrumb events associated with |web_state_|.
// calls from WebStateObserver.
class BreadcrumbManagerTabHelper class BreadcrumbManagerTabHelper
: public web::WebStateObserver, : public infobars::InfoBarManager::Observer,
public web::WebStateObserver,
public web::WebStateUserData<BreadcrumbManagerTabHelper> { public web::WebStateUserData<BreadcrumbManagerTabHelper> {
public: public:
~BreadcrumbManagerTabHelper() override; ~BreadcrumbManagerTabHelper() override;
...@@ -95,10 +112,27 @@ class BreadcrumbManagerTabHelper ...@@ -95,10 +112,27 @@ class BreadcrumbManagerTabHelper
void RenderProcessGone(web::WebState* web_state) override; void RenderProcessGone(web::WebState* web_state) override;
void WebStateDestroyed(web::WebState* web_state) override; void WebStateDestroyed(web::WebState* web_state) override;
// infobars::InfoBarManager::Observer
void OnInfoBarAdded(infobars::InfoBar* infobar) override;
void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override;
void OnInfoBarReplaced(infobars::InfoBar* old_infobar,
infobars::InfoBar* new_infobar) override;
void OnManagerShuttingDown(infobars::InfoBarManager* manager) override;
// The webstate associated with this tab helper. // The webstate associated with this tab helper.
web::WebState* web_state_ = nullptr; web::WebState* web_state_ = nullptr;
int unique_id_ = -1; int unique_id_ = -1;
infobars::InfoBarManager* infobar_manager_ = nullptr;
// A counter which is incremented for each |OnInfoBarReplaced| call. This
// value is reset when any other infobars::InfoBarManager::Observer callback
// is received.
int sequentially_replaced_infobars_ = 0;
// Manages this object as an observer of infobars.
ScopedObserver<infobars::InfoBarManager, infobars::InfoBarManager::Observer>
infobar_observer_;
WEB_STATE_USER_DATA_KEY_DECL(); WEB_STATE_USER_DATA_KEY_DECL();
}; };
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h" #import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_tab_helper.h"
#import "base/ios/ns_error_util.h" #import "base/ios/ns_error_util.h"
#include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_delegate.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/chrome_url_constants.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/net/protocol_handler_util.h" #import "ios/net/protocol_handler_util.h"
#include "ios/web/public/favicon/favicon_url.h" #include "ios/web/public/favicon/favicon_url.h"
#import "ios/web/public/navigation/navigation_context.h" #import "ios/web/public/navigation/navigation_context.h"
...@@ -35,21 +38,30 @@ const char kBreadcrumbDidFinishNavigation[] = "FinishNav"; ...@@ -35,21 +38,30 @@ const char kBreadcrumbDidFinishNavigation[] = "FinishNav";
const char kBreadcrumbPageLoaded[] = "PageLoad"; const char kBreadcrumbPageLoaded[] = "PageLoad";
const char kBreadcrumbDidChangeVisibleSecurityState[] = "SecurityChange"; const char kBreadcrumbDidChangeVisibleSecurityState[] = "SecurityChange";
const char kBreadcrumbInfobarAdded[] = "AddInfobar";
const char kBreadcrumbInfobarRemoved[] = "RemoveInfobar";
const char kBreadcrumbInfobarReplaced[] = "ReplaceInfobar";
const char kBreadcrumbAuthenticationBroken[] = "#broken"; const char kBreadcrumbAuthenticationBroken[] = "#broken";
const char kBreadcrumbDownload[] = "#download"; const char kBreadcrumbDownload[] = "#download";
const char kBreadcrumbMixedContent[] = "#mixed"; const char kBreadcrumbMixedContent[] = "#mixed";
const char kBreadcrumbInfobarNotAnimated[] = "#not-animated";
const char kBreadcrumbNtpNavigation[] = "#ntp"; const char kBreadcrumbNtpNavigation[] = "#ntp";
const char kBreadcrumbPageLoadFailure[] = "#failure"; const char kBreadcrumbPageLoadFailure[] = "#failure";
const char kBreadcrumbRendererInitiatedByUser[] = "#renderer-user"; const char kBreadcrumbRendererInitiatedByUser[] = "#renderer-user";
const char kBreadcrumbRendererInitiatedByScript[] = "#renderer-script"; const char kBreadcrumbRendererInitiatedByScript[] = "#renderer-script";
BreadcrumbManagerTabHelper::BreadcrumbManagerTabHelper(web::WebState* web_state) BreadcrumbManagerTabHelper::BreadcrumbManagerTabHelper(web::WebState* web_state)
: web_state_(web_state) { : web_state_(web_state),
infobar_manager_(InfoBarManagerImpl::FromWebState(web_state)),
infobar_observer_(this) {
DCHECK(web_state_); DCHECK(web_state_);
web_state_->AddObserver(this); web_state_->AddObserver(this);
static int next_unique_id = 1; static int next_unique_id = 1;
unique_id_ = next_unique_id++; unique_id_ = next_unique_id++;
infobar_observer_.Add(infobar_manager_);
} }
BreadcrumbManagerTabHelper::~BreadcrumbManagerTabHelper() = default; BreadcrumbManagerTabHelper::~BreadcrumbManagerTabHelper() = default;
...@@ -169,4 +181,52 @@ void BreadcrumbManagerTabHelper::WebStateDestroyed(web::WebState* web_state) { ...@@ -169,4 +181,52 @@ void BreadcrumbManagerTabHelper::WebStateDestroyed(web::WebState* web_state) {
web_state->RemoveObserver(this); web_state->RemoveObserver(this);
} }
void BreadcrumbManagerTabHelper::OnInfoBarAdded(infobars::InfoBar* infobar) {
sequentially_replaced_infobars_ = 0;
LogEvent(base::StringPrintf("%s%d", kBreadcrumbInfobarAdded,
infobar->delegate()->GetIdentifier()));
}
void BreadcrumbManagerTabHelper::OnInfoBarRemoved(infobars::InfoBar* infobar,
bool animate) {
sequentially_replaced_infobars_ = 0;
std::vector<std::string> event = {
base::StringPrintf("%s%d", kBreadcrumbInfobarRemoved,
infobar->delegate()->GetIdentifier()),
};
if (!animate) {
event.push_back(kBreadcrumbInfobarNotAnimated);
}
LogEvent(base::JoinString(event, " "));
}
void BreadcrumbManagerTabHelper::OnInfoBarReplaced(
infobars::InfoBar* old_infobar,
infobars::InfoBar* new_infobar) {
sequentially_replaced_infobars_++;
if (sequentially_replaced_infobars_ == 1 ||
sequentially_replaced_infobars_ == 2 ||
sequentially_replaced_infobars_ == 5 ||
sequentially_replaced_infobars_ == 20 ||
sequentially_replaced_infobars_ == 100 ||
sequentially_replaced_infobars_ == 200) {
LogEvent(base::StringPrintf("%s%d %d", kBreadcrumbInfobarReplaced,
new_infobar->delegate()->GetIdentifier(),
sequentially_replaced_infobars_));
}
}
void BreadcrumbManagerTabHelper::OnManagerShuttingDown(
infobars::InfoBarManager* manager) {
DCHECK_EQ(infobar_manager_, manager);
infobar_observer_.Remove(manager);
infobar_manager_ = nullptr;
sequentially_replaced_infobars_ = 0;
}
WEB_STATE_USER_DATA_KEY_IMPL(BreadcrumbManagerTabHelper) WEB_STATE_USER_DATA_KEY_IMPL(BreadcrumbManagerTabHelper)
...@@ -6,14 +6,24 @@ ...@@ -6,14 +6,24 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
FakeInfobarDelegate::FakeInfobarDelegate()
: identifier_(infobars::InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR),
message_text_(base::ASCIIToUTF16("FakeInfobarDelegate")) {}
FakeInfobarDelegate::FakeInfobarDelegate(
infobars::InfoBarDelegate::InfoBarIdentifier identifier)
: identifier_(identifier),
message_text_(base::ASCIIToUTF16("FakeInfobarDelegate")) {}
FakeInfobarDelegate::FakeInfobarDelegate(base::string16 message_text) FakeInfobarDelegate::FakeInfobarDelegate(base::string16 message_text)
: message_text_(message_text) {} : identifier_(infobars::InfoBarDelegate::InfoBarIdentifier::TEST_INFOBAR),
message_text_(message_text) {}
FakeInfobarDelegate::~FakeInfobarDelegate() = default; FakeInfobarDelegate::~FakeInfobarDelegate() = default;
infobars::InfoBarDelegate::InfoBarIdentifier infobars::InfoBarDelegate::InfoBarIdentifier
FakeInfobarDelegate::GetIdentifier() const { FakeInfobarDelegate::GetIdentifier() const {
return TEST_INFOBAR; return identifier_;
} }
// Returns the message string to be displayed for the Infobar. // Returns the message string to be displayed for the Infobar.
......
...@@ -12,17 +12,19 @@ ...@@ -12,17 +12,19 @@
// Fake version of InfoBarDelegate. // Fake version of InfoBarDelegate.
class FakeInfobarDelegate : public ConfirmInfoBarDelegate { class FakeInfobarDelegate : public ConfirmInfoBarDelegate {
public: public:
FakeInfobarDelegate( FakeInfobarDelegate();
base::string16 message_text = base::ASCIIToUTF16("FakeInfobarDelegate")); FakeInfobarDelegate(base::string16 message_text);
FakeInfobarDelegate(infobars::InfoBarDelegate::InfoBarIdentifier identifier);
~FakeInfobarDelegate() override; ~FakeInfobarDelegate() override;
// Returns InfoBarIdentifier::TEST_INFOBAR. // Returns |identifier_|, set during construction.
InfoBarIdentifier GetIdentifier() const override; InfoBarIdentifier GetIdentifier() const override;
// Returns the message string to be displayed for the Infobar. // Returns the message string to be displayed for the Infobar.
base::string16 GetMessageText() const override; base::string16 GetMessageText() const override;
private: private:
infobars::InfoBarDelegate::InfoBarIdentifier identifier_;
base::string16 message_text_; base::string16 message_text_;
}; };
......
...@@ -20,6 +20,7 @@ class FakeInfobarIOS : public InfoBarIOS { ...@@ -20,6 +20,7 @@ class FakeInfobarIOS : public InfoBarIOS {
public: public:
FakeInfobarIOS( FakeInfobarIOS(
base::string16 message_text = base::ASCIIToUTF16("FakeInfobar")); base::string16 message_text = base::ASCIIToUTF16("FakeInfobar"));
FakeInfobarIOS(std::unique_ptr<FakeInfobarDelegate> fake_delegate);
~FakeInfobarIOS() override; ~FakeInfobarIOS() override;
// Creates a FakeInfobarIOS whose FakeInfobarUIDelegate's infobar type is // Creates a FakeInfobarIOS whose FakeInfobarUIDelegate's infobar type is
......
...@@ -22,6 +22,17 @@ FakeInfobarIOS::FakeInfobarIOS(base::string16 message_text) ...@@ -22,6 +22,17 @@ FakeInfobarIOS::FakeInfobarIOS(base::string16 message_text)
DCHECK(fake_delegate_); DCHECK(fake_delegate_);
} }
FakeInfobarIOS::FakeInfobarIOS(
std::unique_ptr<FakeInfobarDelegate> fake_delegate)
: InfoBarIOS([[FakeInfobarUIDelegate alloc] init],
std::move(fake_delegate)),
fake_ui_delegate_(
static_cast<FakeInfobarUIDelegate*>(InfobarUIDelegate())),
fake_delegate_(static_cast<FakeInfobarDelegate*>(delegate())) {
DCHECK([fake_ui_delegate_ isKindOfClass:[FakeInfobarUIDelegate class]]);
DCHECK(fake_delegate_);
}
FakeInfobarIOS::~FakeInfobarIOS() = default; FakeInfobarIOS::~FakeInfobarIOS() = default;
// static // static
......
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