Commit ca13511e authored by Mike Dougherty's avatar Mike Dougherty Committed by Commit Bot

[iOS] Collect application breadcrumbs

Existing BreadcrumbManagers are associated with BrowserStates via
BreadcrumbManagerKeyedService instances. This CL adds an application
wide BreadcrumbManager for logging global events not tied to a specific
BrowserState.

Logged events currently come from listening to UserActions and memory
pressure events.

Bug: 1003922
Change-Id: If0e1db381755043d85487e0a85fbb9037abae263
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1987368
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733823}
parent dbe688e4
...@@ -186,6 +186,7 @@ source_set("app_internal") { ...@@ -186,6 +186,7 @@ source_set("app_internal") {
"//ios/chrome/browser/content_settings", "//ios/chrome/browser/content_settings",
"//ios/chrome/browser/crash_report", "//ios/chrome/browser/crash_report",
"//ios/chrome/browser/crash_report:crash_report_internal", "//ios/chrome/browser/crash_report:crash_report_internal",
"//ios/chrome/browser/crash_report/breadcrumbs",
"//ios/chrome/browser/crash_report/breadcrumbs:feature_flags", "//ios/chrome/browser/crash_report/breadcrumbs:feature_flags",
"//ios/chrome/browser/download", "//ios/chrome/browser/download",
"//ios/chrome/browser/external_files", "//ios/chrome/browser/external_files",
......
...@@ -72,6 +72,8 @@ ...@@ -72,6 +72,8 @@
#include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/chrome_url_util.h" #import "ios/chrome/browser/chrome_url_util.h"
#include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.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/features.h" #include "ios/chrome/browser/crash_report/breadcrumbs/features.h"
#include "ios/chrome/browser/crash_report/breakpad_helper.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h"
#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #include "ios/chrome/browser/crash_report/crash_loop_detection_util.h"
...@@ -590,7 +592,9 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData( ...@@ -590,7 +592,9 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData(
self.mainBrowserState = chromeBrowserState; self.mainBrowserState = chromeBrowserState;
if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) {
breakpad::MonitorBreadcrumbsForBrowserState(self.mainBrowserState); breakpad::MonitorBreadcrumbManagerService(
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
self.mainBrowserState));
} }
[self.browserViewWrangler shutdown]; [self.browserViewWrangler shutdown];
...@@ -795,10 +799,13 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData( ...@@ -795,10 +799,13 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData(
if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) {
if (self.mainBrowserState->HasOffTheRecordChromeBrowserState()) { if (self.mainBrowserState->HasOffTheRecordChromeBrowserState()) {
breakpad::StopMonitoringBreadcrumbsForBrowserState( breakpad::StopMonitoringBreadcrumbManagerService(
self.mainBrowserState->GetOffTheRecordChromeBrowserState()); BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
self.mainBrowserState->GetOffTheRecordChromeBrowserState()));
} }
breakpad::StopMonitoringBreadcrumbsForBrowserState(self.mainBrowserState); breakpad::StopMonitoringBreadcrumbManagerService(
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
self.mainBrowserState));
} }
// Invariant: The UI is stopped before the model is shutdown. // Invariant: The UI is stopped before the model is shutdown.
......
...@@ -218,6 +218,9 @@ source_set("browser_impl") { ...@@ -218,6 +218,9 @@ source_set("browser_impl") {
"//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state",
"//ios/chrome/browser/browser_state:browser_state_impl", "//ios/chrome/browser/browser_state:browser_state_impl",
"//ios/chrome/browser/component_updater", "//ios/chrome/browser/component_updater",
"//ios/chrome/browser/crash_report/breadcrumbs",
"//ios/chrome/browser/crash_report/breadcrumbs:application_breadcrumbs_logger",
"//ios/chrome/browser/crash_report/breadcrumbs:feature_flags",
"//ios/chrome/browser/first_run", "//ios/chrome/browser/first_run",
"//ios/chrome/browser/flags", "//ios/chrome/browser/flags",
"//ios/chrome/browser/gcm", "//ios/chrome/browser/gcm",
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
...@@ -42,6 +43,9 @@ ...@@ -42,6 +43,9 @@
#include "ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.h" #include "ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.h"
#include "ios/chrome/browser/chrome_paths.h" #include "ios/chrome/browser/chrome_paths.h"
#include "ios/chrome/browser/component_updater/ios_component_updater_configurator.h" #include "ios/chrome/browser/component_updater/ios_component_updater_configurator.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/features.h"
#include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h" #include "ios/chrome/browser/gcm/ios_chrome_gcm_profile_service_factory.h"
#include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/history/history_service_factory.h"
#include "ios/chrome/browser/ios_chrome_io_thread.h" #include "ios/chrome/browser/ios_chrome_io_thread.h"
...@@ -182,6 +186,13 @@ void ApplicationContextImpl::OnAppEnterForeground() { ...@@ -182,6 +186,13 @@ void ApplicationContextImpl::OnAppEnterForeground() {
ukm::UkmService* ukm_service = GetMetricsServicesManager()->GetUkmService(); ukm::UkmService* ukm_service = GetMetricsServicesManager()->GetUkmService();
if (ukm_service) if (ukm_service)
ukm_service->OnAppEnterForeground(); ukm_service->OnAppEnterForeground();
if (base::FeatureList::IsEnabled(kLogBreadcrumbs) && !breadcrumb_manager_) {
breadcrumb_manager_ = std::make_unique<BreadcrumbManager>();
application_breadcrumbs_logger_ =
std::make_unique<ApplicationBreadcrumbsLogger>(
breadcrumb_manager_.get());
}
} }
void ApplicationContextImpl::OnAppEnterBackground() { void ApplicationContextImpl::OnAppEnterBackground() {
......
...@@ -18,6 +18,9 @@ class CommandLine; ...@@ -18,6 +18,9 @@ class CommandLine;
class SequencedTaskRunner; class SequencedTaskRunner;
} }
class BreadcrumbManager;
class ApplicationBreadcrumbsLogger;
namespace network { namespace network {
class NetworkChangeManager; class NetworkChangeManager;
} }
...@@ -80,6 +83,14 @@ class ApplicationContextImpl : public ApplicationContext { ...@@ -80,6 +83,14 @@ class ApplicationContextImpl : public ApplicationContext {
void CreateGCMDriver(); void CreateGCMDriver();
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
// Breadcrumb manager used to store application wide breadcrumb events. Will
// be null if breadcrumbs feature is not enabled.
std::unique_ptr<BreadcrumbManager> breadcrumb_manager_;
// Logger which observers and logs application wide events to
// |breadcrumb_manager_|. Will be null if breadcrumbs feature is not enabled.
std::unique_ptr<ApplicationBreadcrumbsLogger> application_breadcrumbs_logger_;
std::unique_ptr<PrefService> local_state_; std::unique_ptr<PrefService> local_state_;
std::unique_ptr<net_log::NetExportFileWriter> net_export_file_writer_; std::unique_ptr<net_log::NetExportFileWriter> net_export_file_writer_;
std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_; std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
......
...@@ -49,10 +49,27 @@ source_set("breadcrumbs") { ...@@ -49,10 +49,27 @@ source_set("breadcrumbs") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
} }
source_set("application_breadcrumbs_logger") {
sources = [
"application_breadcrumbs_logger.h",
"application_breadcrumbs_logger.mm",
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
":breadcrumbs",
"//base",
"//ios/chrome/browser/crash_report:crash_report_internal",
"//ios/chrome/browser/crash_report/breadcrumbs",
]
}
source_set("unit_tests") { source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
deps = [ deps = [
":application_breadcrumbs_logger",
":breadcrumbs", ":breadcrumbs",
"//base/test:test_support", "//base/test:test_support",
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
...@@ -68,6 +85,7 @@ source_set("unit_tests") { ...@@ -68,6 +85,7 @@ source_set("unit_tests") {
] ]
sources = [ sources = [
"application_breadcrumbs_logger_unittest.mm",
"breadcrumb_manager_browser_agent_unittest.mm", "breadcrumb_manager_browser_agent_unittest.mm",
"breadcrumb_manager_keyed_service_unittest.mm", "breadcrumb_manager_keyed_service_unittest.mm",
"breadcrumb_manager_observer_bridge_unittest.mm", "breadcrumb_manager_observer_bridge_unittest.mm",
......
// 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 IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_APPLICATION_BREADCRUMBS_LOGGER_H_
#define IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_APPLICATION_BREADCRUMBS_LOGGER_H_
#include <memory>
#include "base/memory/memory_pressure_listener.h"
#include "base/metrics/user_metrics.h"
class BreadcrumbManager;
// Listens for and logs application wide breadcrumb events to the
// BreadcrumbManager passed in the constructor.
class ApplicationBreadcrumbsLogger {
public:
explicit ApplicationBreadcrumbsLogger(BreadcrumbManager* breadcrumb_manager);
~ApplicationBreadcrumbsLogger();
private:
ApplicationBreadcrumbsLogger(const ApplicationBreadcrumbsLogger&) = delete;
// Callback which processes and logs the user action |action| to
// |breadcrumb_manager_|.
void OnUserAction(const std::string& action);
// Callback which processes and logs memory pressure warnings to
// |breadcrumb_manager_|.
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
// The BreadcrumbManager to log events.
BreadcrumbManager* breadcrumb_manager_;
// The callback invoked whenever a user action is registered.
base::ActionCallback user_action_callback_;
// A memory pressure listener which observes memory pressure events.
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
};
#endif // IOS_CHROME_BROWSER_CRASH_REPORT_BREADCRUMBS_APPLICATION_BREADCRUMBS_LOGGER_H_
// 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 "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h"
#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h"
#import "ios/chrome/browser/crash_report/crash_report_helper.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
ApplicationBreadcrumbsLogger::ApplicationBreadcrumbsLogger(
BreadcrumbManager* breadcrumb_manager)
: breadcrumb_manager_(breadcrumb_manager),
user_action_callback_(
base::BindRepeating(&ApplicationBreadcrumbsLogger::OnUserAction,
base::Unretained(this))),
memory_pressure_listener_(std::make_unique<base::MemoryPressureListener>(
base::BindRepeating(&ApplicationBreadcrumbsLogger::OnMemoryPressure,
base::Unretained(this)))) {
base::AddActionCallback(user_action_callback_);
breakpad::MonitorBreadcrumbManager(breadcrumb_manager_);
}
ApplicationBreadcrumbsLogger::~ApplicationBreadcrumbsLogger() {
base::RemoveActionCallback(user_action_callback_);
breakpad::StopMonitoringBreadcrumbManager(breadcrumb_manager_);
}
void ApplicationBreadcrumbsLogger::OnUserAction(const std::string& action) {
// Filter out unwanted actions.
if (action.find("InProductHelp.") == 0) {
// InProductHelp actions are very noisy.
return;
}
std::string event = base::StringPrintf("UserAction: %s", action.c_str());
breadcrumb_manager_->AddEvent(event);
}
void ApplicationBreadcrumbsLogger::OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
std::string pressure_string = "";
switch (memory_pressure_level) {
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
pressure_string = "None";
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
pressure_string = "Moderate";
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
pressure_string = "Critical";
break;
}
std::string event =
base::StringPrintf("Memory Pressure: %s", pressure_string.c_str());
breadcrumb_manager_->AddEvent(event);
}
// 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 "ios/chrome/browser/crash_report/breadcrumbs/application_breadcrumbs_logger.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/metrics/user_metrics_action.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// The particular UserActions used here are not important, but real UserAction
// names are used to prevent a presubmit warning.
const char kUserAction1Name[] = "MobileMenuNewTab";
const char kUserAction2Name[] = "MobileTabClosed";
// An "InProductHelp.*" user action.
const char kInProductHelpUserActionName[] = "InProductHelp.Dismissed";
} // namespace
using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
// Test fixture for testing ApplicationBreadcrumbsLogger class.
class ApplicationBreadcrumbsLoggerTest : public PlatformTest {
protected:
ApplicationBreadcrumbsLoggerTest()
: logger_(std::make_unique<ApplicationBreadcrumbsLogger>(
&breadcrumb_manager_)) {}
base::test::TaskEnvironment task_environment_;
BreadcrumbManager breadcrumb_manager_;
std::unique_ptr<ApplicationBreadcrumbsLogger> logger_;
};
// Tests that a recorded UserAction is logged by the
// ApplicationBreadcrumbsLogger.
TEST_F(ApplicationBreadcrumbsLoggerTest, UserAction) {
base::RecordAction(base::UserMetricsAction(kUserAction1Name));
base::RecordAction(base::UserMetricsAction(kUserAction2Name));
std::list<std::string> events = breadcrumb_manager_.GetEvents(0);
ASSERT_EQ(2ul, events.size());
EXPECT_NE(std::string::npos, events.front().find(kUserAction1Name));
// Ensure UserAction events are labeled as such.
EXPECT_NE(std::string::npos, events.front().find("UserAction: "));
events.pop_front();
EXPECT_NE(std::string::npos, events.front().find(kUserAction2Name));
}
// Tests that "InProductHelp" UserActions are not logged by
// ApplicationBreadcrumbsLogger as they are very noisy.
TEST_F(ApplicationBreadcrumbsLoggerTest, SkipInProductHelpUserActions) {
base::RecordAction(base::UserMetricsAction(kInProductHelpUserActionName));
std::list<std::string> events = breadcrumb_manager_.GetEvents(0);
ASSERT_EQ(0ul, events.size());
}
// Tests that memory pressure events are logged by ApplicationBreadcrumbsLogger.
TEST_F(ApplicationBreadcrumbsLoggerTest, MemoryPressure) {
base::MemoryPressureListener::SimulatePressureNotification(
MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_MODERATE);
base::MemoryPressureListener::SimulatePressureNotification(
MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL);
base::RunLoop().RunUntilIdle();
std::list<std::string> events = breadcrumb_manager_.GetEvents(0);
ASSERT_EQ(2ul, events.size());
EXPECT_NE(std::string::npos, events.front().find("Moderate"));
// Ensure UserAction events are labeled as such.
EXPECT_NE(std::string::npos, events.front().find("Memory Pressure: "));
events.pop_front();
EXPECT_NE(std::string::npos, events.front().find("Critical"));
}
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
@class NSString; @class NSString;
class BreadcrumbManager;
class BreadcrumbManagerKeyedService;
namespace web { namespace web {
class WebState; class WebState;
} // namespace web } // namespace web
...@@ -44,15 +47,21 @@ void StopMonitoringTabStateForWebStateList(WebStateList* web_state_list); ...@@ -44,15 +47,21 @@ void StopMonitoringTabStateForWebStateList(WebStateList* web_state_list);
// be called when the WebStateList is deactivated. // be called when the WebStateList is deactivated.
void ClearStateForWebStateList(WebStateList* web_state_list); void ClearStateForWebStateList(WebStateList* web_state_list);
// Starts listening for breadcrumbs logged to |browser_state|'s // Starts listening for breadcrumbs logged to |breadcrumb_manager|. Collected
// BreadcrumbManagerKeyedService. Collected breadcrumbs will be attached to // breadcrumbs will be attached to crash reports.
// crash reports. void MonitorBreadcrumbManager(BreadcrumbManager* breadcrumb_manager);
void MonitorBreadcrumbsForBrowserState(ios::ChromeBrowserState* browser_state);
// Stops listening for breadcrumbs logged to |breadcrumb_manager|.
void StopMonitoringBreadcrumbManager(BreadcrumbManager* breadcrumb_manager);
// Starts listening for breadcrumbs logged to |breadcrumb_manager_service|.
// Collected breadcrumbs will be attached to crash reports.
void MonitorBreadcrumbManagerService(
BreadcrumbManagerKeyedService* breadcrumb_manager_service);
// Stops listening for breadcrumbs logged to |browser_state|'s // Stops listening for breadcrumbs logged to |breadcrumb_manager_service|.
// BreadcrumbManagerKeyedService. void StopMonitoringBreadcrumbManagerService(
void StopMonitoringBreadcrumbsForBrowserState( BreadcrumbManagerKeyedService* breadcrumb_manager_service);
ios::ChromeBrowserState* browser_state);
} // namespace breakpad } // namespace breakpad
......
...@@ -439,15 +439,26 @@ void ClearStateForWebStateList(WebStateList* web_state_list) { ...@@ -439,15 +439,26 @@ void ClearStateForWebStateList(WebStateList* web_state_list) {
} }
} }
void MonitorBreadcrumbsForBrowserState(ios::ChromeBrowserState* browser_state) { void MonitorBreadcrumbManager(BreadcrumbManager* breadcrumb_manager) {
[[CrashReporterBreadcrumbObserver uniqueInstance] [[CrashReporterBreadcrumbObserver uniqueInstance]
observeBrowserState:browser_state]; observeBreadcrumbManager:breadcrumb_manager];
} }
void StopMonitoringBreadcrumbsForBrowserState( void StopMonitoringBreadcrumbManager(BreadcrumbManager* breadcrumb_manager) {
ios::ChromeBrowserState* browser_state) {
[[CrashReporterBreadcrumbObserver uniqueInstance] [[CrashReporterBreadcrumbObserver uniqueInstance]
stopObservingBrowserState:browser_state]; stopObservingBreadcrumbManager:breadcrumb_manager];
}
void MonitorBreadcrumbManagerService(
BreadcrumbManagerKeyedService* breadcrumb_manager_service) {
[[CrashReporterBreadcrumbObserver uniqueInstance]
observeBreadcrumbManagerService:breadcrumb_manager_service];
}
void StopMonitoringBreadcrumbManagerService(
BreadcrumbManagerKeyedService* breadcrumb_manager_service) {
[[CrashReporterBreadcrumbObserver uniqueInstance]
stopObservingBreadcrumbManagerService:breadcrumb_manager_service];
} }
} // namespace breakpad } // namespace breakpad
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#include "ios/chrome/browser/browser_state/chrome_browser_state_forward.h" #include "ios/chrome/browser/browser_state/chrome_browser_state_forward.h"
#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer_bridge.h" #import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer_bridge.h"
// Combines breadcrumbs from multiple ChromeBrowserState instances and sends the // Combines breadcrumbs from multiple BreadcrumbManagers and sends the merged
// merged breadcrumb events to breakpad for attachment to crash reports. // breadcrumb events to breakpad for attachment to crash reports.
@interface CrashReporterBreadcrumbObserver @interface CrashReporterBreadcrumbObserver
: NSObject <BreadcrumbManagerObserving> { : NSObject <BreadcrumbManagerObserving> {
} }
...@@ -22,10 +22,19 @@ ...@@ -22,10 +22,19 @@
// Creates a singleton instance. // Creates a singleton instance.
+ (CrashReporterBreadcrumbObserver*)uniqueInstance; + (CrashReporterBreadcrumbObserver*)uniqueInstance;
// Starts collecting breadcrumb events associated with |browserState|. // Starts collecting breadcrumb events logged to |breadcrumbManager|.
- (void)observeBrowserState:(ios::ChromeBrowserState*)browserState; - (void)observeBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager;
// Stops collecting breadcrumb events associated with |browserState|.
- (void)stopObservingBrowserState:(ios::ChromeBrowserState*)browserState; // Stops collecting breadcrumb events logged to |breadcrumbManager|.
- (void)stopObservingBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager;
// Starts collecting breadcrumb events logged to |breadcrumbManagerService|.
- (void)observeBreadcrumbManagerService:
(BreadcrumbManagerKeyedService*)breadcrumbManagerService;
// Stops collecting breadcrumb events logged to |breadcrumbManagerService|.
- (void)stopObservingBreadcrumbManagerService:
(BreadcrumbManagerKeyedService*)breadcrumbManagerService;
@end @end
......
...@@ -4,9 +4,8 @@ ...@@ -4,9 +4,8 @@
#include "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h" #include "ios/chrome/browser/crash_report/crash_reporter_breadcrumb_observer.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service.h" #import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_observer_bridge.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_keyed_service_factory.h"
#include "ios/chrome/browser/crash_report/breakpad_helper.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -22,11 +21,17 @@ const int kMaxCombinedBreadcrumbLength = 255; ...@@ -22,11 +21,17 @@ const int kMaxCombinedBreadcrumbLength = 255;
} }
@interface CrashReporterBreadcrumbObserver () { @interface CrashReporterBreadcrumbObserver () {
// Map associating the observed ChromeBrowserStates with the corresponding // Map associating the observed BreadcrumbManager with the corresponding
// observer bridge instances. // observer bridge instances.
std::map<ios::ChromeBrowserState*, std::map<BreadcrumbManager*, std::unique_ptr<BreadcrumbManagerObserverBridge>>
std::unique_ptr<BreadcrumbManagerObserverBridge>>
_breadcrumbManagerObservers; _breadcrumbManagerObservers;
// Map associating the observed BreadcrumbManagerKeyedServices with the
// corresponding observer bridge instances.
std::map<BreadcrumbManagerKeyedService*,
std::unique_ptr<BreadcrumbManagerObserverBridge>>
_breadcrumbManagerServiceObservers;
// A string which stores the received breadcrumbs. Since breakpad will // A string which stores the received breadcrumbs. Since breakpad will
// truncate this string anyway, it is truncated when a new event is added in // truncate this string anyway, it is truncated when a new event is added in
// order to reduce overall memory usage. // order to reduce overall memory usage.
...@@ -49,17 +54,30 @@ const int kMaxCombinedBreadcrumbLength = 255; ...@@ -49,17 +54,30 @@ const int kMaxCombinedBreadcrumbLength = 255;
return self; return self;
} }
- (void)observeBrowserState:(ios::ChromeBrowserState*)browserState { - (void)observeBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager {
DCHECK(!_breadcrumbManagerObservers[browserState]); DCHECK(!_breadcrumbManagerObservers[breadcrumbManager]);
_breadcrumbManagerObservers[breadcrumbManager] =
std::make_unique<BreadcrumbManagerObserverBridge>(breadcrumbManager,
self);
}
- (void)stopObservingBreadcrumbManager:(BreadcrumbManager*)breadcrumbManager {
_breadcrumbManagerObservers.erase(breadcrumbManager);
}
- (void)observeBreadcrumbManagerService:
(BreadcrumbManagerKeyedService*)breadcrumbManagerService {
DCHECK(!_breadcrumbManagerServiceObservers[breadcrumbManagerService]);
BreadcrumbManagerKeyedService* service = _breadcrumbManagerServiceObservers[breadcrumbManagerService] =
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(browserState); std::make_unique<BreadcrumbManagerObserverBridge>(
_breadcrumbManagerObservers[browserState] = breadcrumbManagerService, self);
std::make_unique<BreadcrumbManagerObserverBridge>(service, self);
} }
- (void)stopObservingBrowserState:(ios::ChromeBrowserState*)browserState { - (void)stopObservingBreadcrumbManagerService:
_breadcrumbManagerObservers[browserState] = nullptr; (BreadcrumbManagerKeyedService*)breadcrumbManagerService {
_breadcrumbManagerServiceObservers[breadcrumbManagerService] = nullptr;
} }
#pragma mark - BreadcrumbManagerObserving protocol #pragma mark - BreadcrumbManagerObserving protocol
......
...@@ -95,15 +95,13 @@ TEST_F(CrashReporterBreadcrumbObserverTest, EventsAttachedToCrashReport) { ...@@ -95,15 +95,13 @@ TEST_F(CrashReporterBreadcrumbObserverTest, EventsAttachedToCrashReport) {
[[mock_breakpad_controller_ expect] start:NO]; [[mock_breakpad_controller_ expect] start:NO];
breakpad_helper::SetEnabled(true); breakpad_helper::SetEnabled(true);
CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer =
[[CrashReporterBreadcrumbObserver alloc] init];
[crash_reporter_breadcrumb_observer
observeBrowserState:chrome_browser_state_.get()];
const std::string event = std::string("Breadcrumb Event");
BreadcrumbManagerKeyedService* breadcrumb_service = BreadcrumbManagerKeyedService* breadcrumb_service =
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
chrome_browser_state_.get()); chrome_browser_state_.get());
CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer =
[[CrashReporterBreadcrumbObserver alloc] init];
[crash_reporter_breadcrumb_observer
observeBreadcrumbManagerService:breadcrumb_service];
id breadcrumbs_param_vaidation_block = [OCMArg checkWithBlock:^(id value) { id breadcrumbs_param_vaidation_block = [OCMArg checkWithBlock:^(id value) {
if (![value isKindOfClass:[NSString class]]) { if (![value isKindOfClass:[NSString class]]) {
...@@ -121,7 +119,7 @@ TEST_F(CrashReporterBreadcrumbObserverTest, EventsAttachedToCrashReport) { ...@@ -121,7 +119,7 @@ TEST_F(CrashReporterBreadcrumbObserverTest, EventsAttachedToCrashReport) {
addUploadParameter:breadcrumbs_param_vaidation_block addUploadParameter:breadcrumbs_param_vaidation_block
forKey:@"browser_state_breadcrumbs"]; forKey:@"browser_state_breadcrumbs"];
breadcrumb_service->AddEvent(event); breadcrumb_service->AddEvent(std::string("Breadcrumb Event"));
EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_);
} }
...@@ -136,14 +134,13 @@ TEST_F(CrashReporterBreadcrumbObserverTest, ...@@ -136,14 +134,13 @@ TEST_F(CrashReporterBreadcrumbObserverTest,
const std::string event = std::string("Breadcrumb Event"); const std::string event = std::string("Breadcrumb Event");
NSString* event_nsstring = base::SysUTF8ToNSString(event); NSString* event_nsstring = base::SysUTF8ToNSString(event);
CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer =
[[CrashReporterBreadcrumbObserver alloc] init];
[crash_reporter_breadcrumb_observer
observeBrowserState:chrome_browser_state_.get()];
BreadcrumbManagerKeyedService* breadcrumb_service = BreadcrumbManagerKeyedService* breadcrumb_service =
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
chrome_browser_state_.get()); chrome_browser_state_.get());
CrashReporterBreadcrumbObserver* crash_reporter_breadcrumb_observer =
[[CrashReporterBreadcrumbObserver alloc] init];
[crash_reporter_breadcrumb_observer
observeBreadcrumbManagerService:breadcrumb_service];
[[mock_breakpad_controller_ expect] [[mock_breakpad_controller_ expect]
addUploadParameter:StringParameterValidatorWithCountOfSubstring( addUploadParameter:StringParameterValidatorWithCountOfSubstring(
...@@ -153,10 +150,11 @@ TEST_F(CrashReporterBreadcrumbObserverTest, ...@@ -153,10 +150,11 @@ TEST_F(CrashReporterBreadcrumbObserverTest,
ios::ChromeBrowserState* otr_browser_state = ios::ChromeBrowserState* otr_browser_state =
chrome_browser_state_->GetOffTheRecordChromeBrowserState(); chrome_browser_state_->GetOffTheRecordChromeBrowserState();
[crash_reporter_breadcrumb_observer observeBrowserState:otr_browser_state];
BreadcrumbManagerKeyedService* otr_breadcrumb_service = BreadcrumbManagerKeyedService* otr_breadcrumb_service =
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
otr_browser_state); otr_browser_state);
[crash_reporter_breadcrumb_observer
observeBreadcrumbManagerService:otr_breadcrumb_service];
[[mock_breakpad_controller_ expect] [[mock_breakpad_controller_ expect]
addUploadParameter:StringParameterValidatorWithCountOfSubstring( addUploadParameter:StringParameterValidatorWithCountOfSubstring(
...@@ -167,11 +165,11 @@ TEST_F(CrashReporterBreadcrumbObserverTest, ...@@ -167,11 +165,11 @@ TEST_F(CrashReporterBreadcrumbObserverTest,
TestChromeBrowserState::Builder test_cbs_builder; TestChromeBrowserState::Builder test_cbs_builder;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_2 = std::unique_ptr<TestChromeBrowserState> chrome_browser_state_2 =
test_cbs_builder.Build(); test_cbs_builder.Build();
[crash_reporter_breadcrumb_observer
observeBrowserState:chrome_browser_state_2.get()];
BreadcrumbManagerKeyedService* breadcrumb_service_2 = BreadcrumbManagerKeyedService* breadcrumb_service_2 =
BreadcrumbManagerKeyedServiceFactory::GetForBrowserState( BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
chrome_browser_state_2.get()); chrome_browser_state_2.get());
[crash_reporter_breadcrumb_observer
observeBreadcrumbManagerService:breadcrumb_service_2];
[[mock_breakpad_controller_ expect] [[mock_breakpad_controller_ expect]
addUploadParameter:StringParameterValidatorWithCountOfSubstring( addUploadParameter:StringParameterValidatorWithCountOfSubstring(
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/chrome_url_constants.h"
#import "ios/chrome/browser/chrome_url_util.h" #import "ios/chrome/browser/chrome_url_util.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.h" #include "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_manager_browser_agent.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/features.h" #include "ios/chrome/browser/crash_report/breadcrumbs/features.h"
#include "ios/chrome/browser/crash_report/breakpad_helper.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h"
#include "ios/chrome/browser/crash_report/crash_report_helper.h" #include "ios/chrome/browser/crash_report/crash_report_helper.h"
...@@ -1303,15 +1305,17 @@ enum class EnterTabSwitcherSnapshotResult { ...@@ -1303,15 +1305,17 @@ enum class EnterTabSwitcherSnapshotResult {
BreadcrumbManagerBrowserAgent::FromBrowser(self.incognitoInterface.browser) BreadcrumbManagerBrowserAgent::FromBrowser(self.incognitoInterface.browser)
->SetLoggingEnabled(false); ->SetLoggingEnabled(false);
breakpad::StopMonitoringBreadcrumbsForBrowserState( breakpad::StopMonitoringBreadcrumbManagerService(
self.incognitoInterface.browserState); BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
self.incognitoInterface.browserState));
} }
[self.mainController.browserViewWrangler destroyAndRebuildIncognitoBrowser]; [self.mainController.browserViewWrangler destroyAndRebuildIncognitoBrowser];
if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) { if (base::FeatureList::IsEnabled(kLogBreadcrumbs)) {
breakpad::MonitorBreadcrumbsForBrowserState( breakpad::MonitorBreadcrumbManagerService(
self.incognitoInterface.browserState); BreadcrumbManagerKeyedServiceFactory::GetForBrowserState(
self.incognitoInterface.browserState));
} }
if (otrBVCIsCurrent) { if (otrBVCIsCurrent) {
......
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