| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/breadcrumbs/core/application_breadcrumbs_logger.h" |
| |
| #include <algorithm> |
| |
| #include "base/functional/bind.h" |
| #include "base/strings/stringprintf.h" |
| #include "components/breadcrumbs/core/application_breadcrumbs_not_user_action.inc" |
| #include "components/breadcrumbs/core/breadcrumb_manager.h" |
| #include "components/breadcrumbs/core/breadcrumb_persistent_storage_manager.h" |
| |
| #if defined(TOOLKIT_VIEWS) |
| #include "ui/views/widget/any_widget_observer_singleton.h" |
| #include "ui/views/widget/widget.h" |
| #endif // TOOLKIT_VIEWS |
| |
| namespace breadcrumbs { |
| |
| namespace { |
| |
| void AddEvent(const std::string& event) { |
| breadcrumbs::BreadcrumbManager::GetInstance().AddEvent(event); |
| } |
| |
| } // namespace |
| |
| ApplicationBreadcrumbsLogger::ApplicationBreadcrumbsLogger( |
| const base::FilePath& storage_dir, |
| base::RepeatingCallback<bool()> is_metrics_enabled_callback) |
| : user_action_callback_( |
| base::BindRepeating(&ApplicationBreadcrumbsLogger::OnUserAction, |
| base::Unretained(this))), |
| memory_pressure_listener_(std::make_unique<base::MemoryPressureListener>( |
| FROM_HERE, |
| base::MemoryPressureListenerTag::kApplicationBreadcrumbsLogger, |
| base::BindRepeating(&ApplicationBreadcrumbsLogger::OnMemoryPressure, |
| base::Unretained(this)))), |
| #if defined(TOOLKIT_VIEWS) |
| any_widget_observer_(views::AnyWidgetPasskey{}), |
| #endif // TOOLKIT_VIEWS |
| persistent_storage_manager_( |
| std::make_unique<BreadcrumbPersistentStorageManager>( |
| storage_dir, |
| std::move(is_metrics_enabled_callback))) { |
| base::AddActionCallback(user_action_callback_); |
| #if defined(TOOLKIT_VIEWS) |
| any_widget_observer_.set_closing_callback(base::BindRepeating( |
| &ApplicationBreadcrumbsLogger::OnWidgetClosed, base::Unretained(this))); |
| #endif // TOOLKIT_VIEWS |
| AddEvent("Startup"); |
| } |
| |
| ApplicationBreadcrumbsLogger::~ApplicationBreadcrumbsLogger() { |
| AddEvent("Shutdown"); |
| base::RemoveActionCallback(user_action_callback_); |
| } |
| |
| BreadcrumbPersistentStorageManager* |
| ApplicationBreadcrumbsLogger::GetPersistentStorageManager() const { |
| return persistent_storage_manager_.get(); |
| } |
| |
| void ApplicationBreadcrumbsLogger::OnUserAction(const std::string& action, |
| base::TimeTicks action_time) { |
| // Filter out unwanted actions. |
| if (action.find("InProductHelp.") == 0) { |
| // InProductHelp actions are very noisy. |
| return; |
| } |
| |
| if (!IsUserTriggeredAction(action)) { |
| // These actions are not useful for breadcrumbs. |
| return; |
| } |
| |
| AddEvent(action.c_str()); |
| } |
| |
| void ApplicationBreadcrumbsLogger::OnMemoryPressure( |
| base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { |
| const char* 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; |
| } |
| |
| AddEvent(base::StringPrintf("Memory Pressure: %s", pressure_string)); |
| } |
| |
| #if defined(TOOLKIT_VIEWS) |
| void ApplicationBreadcrumbsLogger::OnWidgetClosed(views::Widget* widget) { |
| AddEvent(base::StringPrintf("Widget Closed: %s", widget->GetName().c_str())); |
| } |
| #endif // TOOLKIT_VIEWS |
| |
| bool ApplicationBreadcrumbsLogger::IsUserTriggeredAction( |
| const std::string& action) { |
| // The variable kNotUserTriggeredActions is a sorted array of |
| // strings generated by generate_not_user_triggered_actions.py. |
| // It is defined in application_breadcrumbs_not_user_action.inc. |
| return !std::binary_search(std::begin(kNotUserTriggeredActions), |
| std::end(kNotUserTriggeredActions), action); |
| } |
| |
| } // namespace breadcrumbs |