Commit 3a669b06 authored by tby's avatar tby Committed by Commit Bot

[Hashed logging] Refactor API and internal logic.

This is the first change to convert the existing hashed logging code
into a general framework. This CL mostly removes code that was specific
to the search ranking use of hashed logging, and also changes the
API for logging.

Note that all hashed logging has been disabled for this refactor.

We need to delete this code now because there's a chain of
dependencies between the refactoring CLs. Roughly:

 1. Code referencing the current proto used to report logs must be
    deleted.

 2. The proto itself can then be changed internally, and re-exported
    to chromium. This has to be done as a unitary CL, with no other
    changes.

 3. Then, code can be re-added that references the new version of the
    proto.

Detailed changes:

 1. AppListLaunchRecorder::Record has become ::Log, which now takes
    lists of hashed and unhashed data. This is a tentative first try
    at the new API.

 2. The core hashed logic in AppListLaunchMetricsProvider has been
    deleted, because it will need to be generalized.

 3. The unit tests have all been disabled and the core EXPECT logic
    removed. This too must be rewritten for the generalized version.

Bug: 1016655
Change-Id: Iccc98771003c602b1a8375b4b2898e077f28def6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1874411Reviewed-by: default avatarThanh Nguyen <thanhdng@chromium.org>
Commit-Queue: Tony Yeoman <tby@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709329}
parent d71f2633
...@@ -30,8 +30,6 @@ ...@@ -30,8 +30,6 @@
namespace app_list { namespace app_list {
namespace { namespace {
using LaunchInfo = AppListLaunchRecorder::LaunchInfo;
using ::metrics::ChromeOSAppListLaunchEventProto; using ::metrics::ChromeOSAppListLaunchEventProto;
using ::metrics::ChromeUserMetricsExtension; using ::metrics::ChromeUserMetricsExtension;
using ::metrics::MetricsLog; using ::metrics::MetricsLog;
...@@ -250,7 +248,7 @@ void AppListLaunchMetricsProvider::ProvideCurrentSessionData( ...@@ -250,7 +248,7 @@ void AppListLaunchMetricsProvider::ProvideCurrentSessionData(
} }
void AppListLaunchMetricsProvider::OnAppListLaunch( void AppListLaunchMetricsProvider::OnAppListLaunch(
const LaunchInfo& launch_info) { const AppListLaunchRecorder::LaunchInfo& launch_info) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (init_state_ == InitState::UNINITIALIZED) { if (init_state_ == InitState::UNINITIALIZED) {
init_state_ = InitState::INIT_STARTED; init_state_ = InitState::INIT_STARTED;
...@@ -261,8 +259,7 @@ void AppListLaunchMetricsProvider::OnAppListLaunch( ...@@ -261,8 +259,7 @@ void AppListLaunchMetricsProvider::OnAppListLaunch(
launch_info_cache_.size() >= static_cast<size_t>(kMaxEventsPerUpload)) launch_info_cache_.size() >= static_cast<size_t>(kMaxEventsPerUpload))
return; return;
if (launch_info.launch_type == if (launch_info.client == AppListLaunchRecorder::Client::kUnspecified) {
ChromeOSAppListLaunchEventProto::LAUNCH_TYPE_UNSPECIFIED) {
LogMetricsProviderError(MetricsProviderError::kLaunchTypeUnspecified); LogMetricsProviderError(MetricsProviderError::kLaunchTypeUnspecified);
return; return;
} }
...@@ -277,7 +274,7 @@ void AppListLaunchMetricsProvider::OnAppListLaunch( ...@@ -277,7 +274,7 @@ void AppListLaunchMetricsProvider::OnAppListLaunch(
} }
void AppListLaunchMetricsProvider::CreateLaunchEvent( void AppListLaunchMetricsProvider::CreateLaunchEvent(
const LaunchInfo& launch_info, const AppListLaunchRecorder::LaunchInfo& launch_info,
ChromeOSAppListLaunchEventProto* event) { ChromeOSAppListLaunchEventProto* event) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(secret_ && user_id_); DCHECK(secret_ && user_id_);
...@@ -285,18 +282,11 @@ void AppListLaunchMetricsProvider::CreateLaunchEvent( ...@@ -285,18 +282,11 @@ void AppListLaunchMetricsProvider::CreateLaunchEvent(
base::Time::Exploded now; base::Time::Exploded now;
base::Time::Now().LocalExplode(&now); base::Time::Now().LocalExplode(&now);
// Unhashed data. // TODO(crbug.com/1016655): set hashed and unhashed data after proto has been
event->set_recurrence_ranker_user_id(user_id_.value()); // updated.
event->set_hour(now.hour);
event->set_search_query_length(launch_info.query.size()); // Dummy call so that HashWithSecret compiles.
event->set_launch_type(launch_info.launch_type); LOG(ERROR) << HashWithSecret("dummy hash", secret_.value());
event->set_search_provider_type(launch_info.search_provider_type);
// Hashed data.
event->set_hashed_target(HashWithSecret(launch_info.target, secret_.value()));
event->set_hashed_query(HashWithSecret(launch_info.query, secret_.value()));
event->set_hashed_domain(HashWithSecret(launch_info.domain, secret_.value()));
event->set_hashed_app(HashWithSecret(launch_info.app, secret_.value()));
} }
} // namespace app_list } // namespace app_list
...@@ -10,26 +10,9 @@ ...@@ -10,26 +10,9 @@
namespace app_list { namespace app_list {
using LaunchInfo = AppListLaunchRecorder::LaunchInfo; AppListLaunchRecorder::LaunchInfo::LaunchInfo() = default;
AppListLaunchRecorder::LaunchInfo::LaunchInfo(
metrics::ChromeOSAppListLaunchEventProto::LaunchType launch_type,
metrics::ChromeOSAppListLaunchEventProto::SearchProviderType
search_provider_type,
const std::string& target,
const std::string& query,
const std::string& domain,
const std::string& app)
: launch_type(launch_type),
search_provider_type(search_provider_type),
target(target),
query(query),
domain(domain),
app(app) {}
AppListLaunchRecorder::LaunchInfo::LaunchInfo(const LaunchInfo& other) = AppListLaunchRecorder::LaunchInfo::LaunchInfo(const LaunchInfo& other) =
default; default;
AppListLaunchRecorder::LaunchInfo::~LaunchInfo() = default; AppListLaunchRecorder::LaunchInfo::~LaunchInfo() = default;
AppListLaunchRecorder* AppListLaunchRecorder::GetInstance() { AppListLaunchRecorder* AppListLaunchRecorder::GetInstance() {
...@@ -46,12 +29,4 @@ AppListLaunchRecorder::RegisterCallback(const LaunchEventCallback& callback) { ...@@ -46,12 +29,4 @@ AppListLaunchRecorder::RegisterCallback(const LaunchEventCallback& callback) {
return callback_list_.Add(callback); return callback_list_.Add(callback);
} }
// Notifies all observers of the given |launch_info|. If the
// AppListMetricsProvider has been constructed, this will queue an
// AppListLaunchEvent to be provided to the metrics service.
void AppListLaunchRecorder::Record(const LaunchInfo& launch_info) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
callback_list_.Notify(launch_info);
}
} // namespace app_list } // namespace app_list
...@@ -7,8 +7,11 @@ ...@@ -7,8 +7,11 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include <vector>
#include "base/callback_list.h" #include "base/callback_list.h"
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/observer_list.h" #include "base/observer_list.h"
...@@ -17,72 +20,71 @@ ...@@ -17,72 +20,71 @@
namespace app_list { namespace app_list {
class SearchController; class AppListLaunchMetricsProvider;
// AppListLaunchRecorder is a singleton that can be called to send hashed // TODO(crbug.com/1016655): add comments and documentation once the API has been
// logging events to UMA. Typical usage is: // finalized.
//
// AppListLaunchRecorder::GetInstance()->Record(my_data);
//
// This should only be called from the browser UI thread.
class AppListLaunchRecorder { class AppListLaunchRecorder {
public: public:
// Stores information about a single launch event to be logged by a call to // Lists all clients using thie logging system. Each project should have an
// Record. // entry here. These values are persisted to logs. Entries should not be
// renumbered and numeric values should never be reused.
// TODO(crbug.com/1016655): add additional explanation for what it means to
// add a separate project (eg. different IDs) once the design has been
// finalized.
enum class Client {
kUnspecified = 0,
kTesting = 1,
kLauncher = 2,
};
struct LaunchInfo { struct LaunchInfo {
LaunchInfo(metrics::ChromeOSAppListLaunchEventProto::LaunchType launch_type, LaunchInfo();
metrics::ChromeOSAppListLaunchEventProto::SearchProviderType
search_provider_type,
const std::string& target,
const std::string& query,
const std::string& domain,
const std::string& app);
LaunchInfo(const LaunchInfo& other); LaunchInfo(const LaunchInfo& other);
~LaunchInfo(); ~LaunchInfo();
// Specifies which UI component this event was launched from. AppListLaunchRecorder::Client client;
metrics::ChromeOSAppListLaunchEventProto::LaunchType launch_type; std::vector<std::pair<int, std::string>> hashed;
// Specifies which search provider created this event's result. std::vector<std::pair<int, int>> unhashed;
metrics::ChromeOSAppListLaunchEventProto::SearchProviderType
search_provider_type;
// A string identifier of the item being launched, eg. an app ID or
// filepath.
std::string target;
// The search query at the time of launch. If this is a zero-state launch
// (eg. from the suggested chips), this should be the empty string.
std::string query;
// The last-visited domain at the time of launch.
std::string domain;
// The app ID of the last-opened app at the time of launch.
std::string app;
}; };
using LaunchEventCallback =
base::RepeatingCallback<void(const AppListLaunchRecorder::LaunchInfo&)>;
using LaunchEventSubscription = base::CallbackList<void(
const AppListLaunchRecorder::LaunchInfo&)>::Subscription;
// Returns the instance of AppListLaunchRecorder.
static AppListLaunchRecorder* GetInstance(); static AppListLaunchRecorder* GetInstance();
// Registers a callback to be invoked on a call to Record().
std::unique_ptr<LaunchEventSubscription> RegisterCallback(
const LaunchEventCallback& callback);
private: private:
friend class base::NoDestructor<AppListLaunchRecorder>; friend class base::NoDestructor<AppListLaunchRecorder>;
friend class app_list::AppListLaunchMetricsProvider;
// These are the clients of hashed logging: using EventFn = void(const LaunchInfo&);
friend class SearchController; using LaunchEventCallback = base::RepeatingCallback<EventFn>;
using LaunchEventCallbackList = base::CallbackList<EventFn>;
// Adds |launch_info| to the cache of launches to be hashed and provided to using LaunchEventSubscription = LaunchEventCallbackList::Subscription;
// the metrics service on a call to ProvideCurrentSessionData.
void Record(const LaunchInfo& launch_info);
AppListLaunchRecorder(); AppListLaunchRecorder();
~AppListLaunchRecorder(); ~AppListLaunchRecorder();
base::CallbackList<void(const LaunchInfo&)> callback_list_; template <typename T>
void Log(Client client,
const std::vector<std::pair<T, std::string>>& hashed,
const std::vector<std::pair<T, int>>& unhashed) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
static_assert(std::is_enum<T>::value,
"Non enum passed to AppListLaunchRecorder::Log");
LaunchInfo event;
event.client = client;
for (const auto& pair : hashed)
event.hashed.push_back({static_cast<int>(pair.first), pair.second});
for (const auto& pair : unhashed)
event.unhashed.push_back({static_cast<int>(pair.first), pair.second});
callback_list_.Notify(event);
}
// Registers a callback to be invoked on a call to Log().
std::unique_ptr<LaunchEventSubscription> RegisterCallback(
const LaunchEventCallback& callback);
LaunchEventCallbackList callback_list_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
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