Commit d4dd1e12 authored by Eugene But's avatar Eugene But Committed by Commit Bot

Support batch WebStateList mutations in BreadcrumbManagerBrowserAgent

WebStateList supports batch operation (f.e. used in Close All Tabs
and Undo Close All Tabs actions). These batch operations may call
the same WebStateListObserver callback multiple times which creates
a lot of noise in breadcrumb logs.

This CL adds support for Insert and Close batch operations and only
logs the number of inserted or closed WebState objects.

Additional changes:
 - Remove WebStateDetachedAt because it's always coupled with
   WillCloseWebStateAt and does not add anything on its own
 - Remove _ from "Browser_<id>" to be consistent with logging
   "Tab<id>"

Bug: 1046231
Change-Id: I11429a281bf8d7c343132c02e4b92f463aa8a7ea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2082484
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Auto-Submit: Eugene But <eugenebut@chromium.org>
Reviewed-by: default avatarMike Dougherty <michaeldo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#746289}
parent 2d9bb593
...@@ -34,6 +34,8 @@ class BreadcrumbManagerBrowserAgent ...@@ -34,6 +34,8 @@ class BreadcrumbManagerBrowserAgent
bool IsLoggingEnabled(); bool IsLoggingEnabled();
void SetLoggingEnabled(bool enabled); void SetLoggingEnabled(bool enabled);
~BreadcrumbManagerBrowserAgent() override;
private: private:
explicit BreadcrumbManagerBrowserAgent(Browser* browser); explicit BreadcrumbManagerBrowserAgent(Browser* browser);
friend class BrowserUserData<BreadcrumbManagerBrowserAgent>; friend class BrowserUserData<BreadcrumbManagerBrowserAgent>;
...@@ -64,9 +66,6 @@ class BreadcrumbManagerBrowserAgent ...@@ -64,9 +66,6 @@ class BreadcrumbManagerBrowserAgent
web::WebState* old_web_state, web::WebState* old_web_state,
web::WebState* new_web_state, web::WebState* new_web_state,
int index) override; int index) override;
void WebStateDetachedAt(WebStateList* web_state_list,
web::WebState* web_state,
int index) override;
void WillCloseWebStateAt(WebStateList* web_state_list, void WillCloseWebStateAt(WebStateList* web_state_list,
web::WebState* web_state, web::WebState* web_state,
int index, int index,
...@@ -76,6 +75,8 @@ class BreadcrumbManagerBrowserAgent ...@@ -76,6 +75,8 @@ class BreadcrumbManagerBrowserAgent
web::WebState* new_web_state, web::WebState* new_web_state,
int active_index, int active_index,
int reason) override; int reason) override;
void WillBeginBatchOperation(WebStateList* web_state_list) override;
void BatchOperationEnded(WebStateList* web_state_list) override;
// Unique (across this application run only) identifier for logs associated // Unique (across this application run only) identifier for logs associated
// with |browser_| instance. Used to differentiate logs associated with the // with |browser_| instance. Used to differentiate logs associated with the
...@@ -84,6 +85,19 @@ class BreadcrumbManagerBrowserAgent ...@@ -84,6 +85,19 @@ class BreadcrumbManagerBrowserAgent
// Whether or not events will be logged. // Whether or not events will be logged.
bool logging_enabled_ = true; bool logging_enabled_ = true;
Browser* browser_ = nullptr; Browser* browser_ = nullptr;
// Keeps track of WebState mutation count to avoid logging every event.
// Created in WillBeginBatchOperation and destroyed in BatchOperationEnded.
// Final mutation count is logged in BatchOperationEnded.
struct BatchOperation {
// Number of WebState objects inserted between WillBeginBatchOperation and
// BatchOperationEnded callbacks.
int insertion_count = 0;
// Number of WebState objects closed between WillBeginBatchOperation and
// BatchOperationEnded callbacks.
int close_count = 0;
};
std::unique_ptr<BatchOperation> batch_operation_;
}; };
#endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_BROWSER_AGENT_H_ #endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_BREADCRUMB_MANAGER_BROWSER_AGENT_H_
...@@ -28,6 +28,8 @@ BreadcrumbManagerBrowserAgent::BreadcrumbManagerBrowserAgent(Browser* browser) ...@@ -28,6 +28,8 @@ BreadcrumbManagerBrowserAgent::BreadcrumbManagerBrowserAgent(Browser* browser)
browser_->GetWebStateList()->AddObserver(this); browser_->GetWebStateList()->AddObserver(this);
} }
BreadcrumbManagerBrowserAgent::~BreadcrumbManagerBrowserAgent() = default;
bool BreadcrumbManagerBrowserAgent::IsLoggingEnabled() { bool BreadcrumbManagerBrowserAgent::IsLoggingEnabled() {
return logging_enabled_; return logging_enabled_;
} }
...@@ -50,7 +52,7 @@ void BreadcrumbManagerBrowserAgent::LogEvent(const std::string& event) { ...@@ -50,7 +52,7 @@ void BreadcrumbManagerBrowserAgent::LogEvent(const std::string& event) {
BreadcrumbManagerKeyedServiceFactory::GetInstance()->GetForBrowserState( BreadcrumbManagerKeyedServiceFactory::GetInstance()->GetForBrowserState(
browser_->GetBrowserState()); browser_->GetBrowserState());
breadcrumb_manager->AddEvent( breadcrumb_manager->AddEvent(
base::StringPrintf("Browser_%d %s", unique_id_, event.c_str())); base::StringPrintf("Browser%d %s", unique_id_, event.c_str()));
} }
void BreadcrumbManagerBrowserAgent::WebStateInsertedAt( void BreadcrumbManagerBrowserAgent::WebStateInsertedAt(
...@@ -58,6 +60,11 @@ void BreadcrumbManagerBrowserAgent::WebStateInsertedAt( ...@@ -58,6 +60,11 @@ void BreadcrumbManagerBrowserAgent::WebStateInsertedAt(
web::WebState* web_state, web::WebState* web_state,
int index, int index,
bool activating) { bool activating) {
if (batch_operation_) {
++batch_operation_->insertion_count;
return;
}
int web_state_id = int web_state_id =
BreadcrumbManagerTabHelper::FromWebState(web_state)->GetUniqueId(); BreadcrumbManagerTabHelper::FromWebState(web_state)->GetUniqueId();
const char* activating_string = activating ? "active" : "inactive"; const char* activating_string = activating ? "active" : "inactive";
...@@ -85,19 +92,16 @@ void BreadcrumbManagerBrowserAgent::WebStateReplacedAt( ...@@ -85,19 +92,16 @@ void BreadcrumbManagerBrowserAgent::WebStateReplacedAt(
LogEvent(base::StringPrintf("Replaced Tab%d with Tab%d at %d", LogEvent(base::StringPrintf("Replaced Tab%d with Tab%d at %d",
old_web_state_id, new_web_state_id, index)); old_web_state_id, new_web_state_id, index));
} }
void BreadcrumbManagerBrowserAgent::WebStateDetachedAt(
WebStateList* web_state_list,
web::WebState* web_state,
int index) {
int web_state_id =
BreadcrumbManagerTabHelper::FromWebState(web_state)->GetUniqueId();
LogEvent(base::StringPrintf("Tab%d detached at %d", web_state_id, index));
}
void BreadcrumbManagerBrowserAgent::WillCloseWebStateAt( void BreadcrumbManagerBrowserAgent::WillCloseWebStateAt(
WebStateList* web_state_list, WebStateList* web_state_list,
web::WebState* web_state, web::WebState* web_state,
int index, int index,
bool user_action) { bool user_action) {
if (batch_operation_) {
++batch_operation_->close_count;
return;
}
int web_state_id = int web_state_id =
BreadcrumbManagerTabHelper::FromWebState(web_state)->GetUniqueId(); BreadcrumbManagerTabHelper::FromWebState(web_state)->GetUniqueId();
const char* user_action_string = user_action ? " by user action" : ""; const char* user_action_string = user_action ? " by user action" : "";
...@@ -137,3 +141,23 @@ void BreadcrumbManagerBrowserAgent::WebStateActivatedAt( ...@@ -137,3 +141,23 @@ void BreadcrumbManagerBrowserAgent::WebStateActivatedAt(
old_web_state_id, change_reason_string, old_web_state_id, change_reason_string,
new_web_state_id, active_index)); new_web_state_id, active_index));
} }
void BreadcrumbManagerBrowserAgent::WillBeginBatchOperation(
WebStateList* web_state_list) {
batch_operation_ = std::make_unique<BatchOperation>();
}
void BreadcrumbManagerBrowserAgent::BatchOperationEnded(
WebStateList* web_state_list) {
if (batch_operation_) {
if (batch_operation_->insertion_count > 0) {
LogEvent(base::StringPrintf("Inserted %d tabs",
batch_operation_->insertion_count));
}
if (batch_operation_->close_count > 0) {
LogEvent(
base::StringPrintf("Closed %d tabs", batch_operation_->close_count));
}
}
batch_operation_.reset();
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.h" #import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.h"
#include "base/bind.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.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"
...@@ -123,3 +124,40 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) { ...@@ -123,3 +124,40 @@ TEST_F(BreadcrumbManagerBrowserAgentTest, MultipleBrowsers) {
browser2_split_pos, events.back().length() - browser2_split_pos); browser2_split_pos, events.back().length() - browser2_split_pos);
EXPECT_STRNE(browser1_end.c_str(), browser2_end.c_str()); EXPECT_STRNE(browser1_end.c_str(), browser2_end.c_str());
} }
// Tests WebStateList's batch insertion and closing.
TEST_F(BreadcrumbManagerBrowserAgentTest, BatchOperations) {
WebStateList web_state_list(&web_state_list_delegate_);
std::unique_ptr<Browser> browser =
std::make_unique<TestBrowser>(browser_state_.get(), &web_state_list);
BreadcrumbManagerBrowserAgent::CreateForBrowser(browser.get());
// Insert multiple WebStates.
web_state_list.PerformBatchOperation(base::BindOnce(^(WebStateList* list) {
web::WebState::CreateParams create_params(browser_state_.get());
list->InsertWebState(
/*index=*/0, web::WebState::Create(create_params),
WebStateList::InsertionFlags::INSERT_NO_FLAGS, WebStateOpener());
list->InsertWebState(
/*index=*/1, web::WebState::Create(create_params),
WebStateList::InsertionFlags::INSERT_NO_FLAGS, WebStateOpener());
}));
std::list<std::string> events = breadcrumb_service_->GetEvents(0);
ASSERT_EQ(1ul, events.size());
EXPECT_NE(std::string::npos, events.front().find("Inserted 2 tabs"))
<< events.front();
// Close multiple WebStates.
web_state_list.PerformBatchOperation(base::BindOnce(^(WebStateList* list) {
list->CloseWebStateAt(
/*index=*/0, WebStateList::ClosingFlags::CLOSE_NO_FLAGS);
list->CloseWebStateAt(
/*index=*/0, WebStateList::ClosingFlags::CLOSE_NO_FLAGS);
}));
events = breadcrumb_service_->GetEvents(0);
ASSERT_EQ(2ul, events.size());
EXPECT_NE(std::string::npos, events.back().find("Closed 2 tabs"))
<< events.back();
}
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