1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_APP_LIST_SEARCH_FEDERATED_METRICS_MANAGER_H_
#define CHROME_BROWSER_ASH_APP_LIST_SEARCH_FEDERATED_METRICS_MANAGER_H_
#include <optional>
#include <string>
#include <vector>
#include "ash/public/cpp/app_list/app_list_metrics.h"
#include "ash/public/cpp/app_list/app_list_notifier.h"
#include "ash/system/federated/federated_service_controller.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chromeos/ash/services/federated/public/cpp/service_connection.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace app_list::federated {
inline constexpr char kHistogramSearchSessionConclusion[] =
"Apps.AppList.Search.Federated.SearchSessionConclusion";
inline constexpr char kHistogramInitStatus[] =
"Apps.AppList.Search.Federated.InitStatus";
inline constexpr char kHistogramQueryLengthOnStorageSuccess[] =
"Apps.AppList.Search.Federated.QueryLengthOnStorageSuccess";
inline constexpr char kHistogramReportStatus[] =
"Apps.AppList.Search.Federated.ReportStatus";
inline constexpr int kMaxLoggedQueryLengthOnStorageSuccess = 20;
// Records launcher search backend federated analytics.
// Requires that OnDefaultSearchIsGoogleSet() is called after class creation and
// before any logging is triggered. Enforced by a CHECK().
//
// TODO(b/289140140): Consider migrating to FederatedClientManager utility class
// after that class is completed.
class FederatedMetricsManager : ash::AppListNotifier::Observer {
public:
using Result = ash::AppListNotifier::Result;
using Location = ash::AppListNotifier::Location;
// Represents the actions a user can take in the launcher. These values
// persist to logs. Entries should not be renumbered and numeric values should
// never be reused.
// TODO(b/262611120): Currently unused. Deprecate if remains unused.
enum class Action {
kImpression = 0,
kLaunch = 1,
kAbandon = 2,
kIgnore = 3,
kMaxValue = kIgnore
};
// Represents possible states in the initialization of the federated metrics
// manager itself. These values persist to logs. Entries should not be
// renumbered and numeric values should never be reused.
enum class InitStatus {
kOk = 0,
kMissingNotifier = 1,
kMissingController = 2,
kFederatedConnectionFailedToEstablish = 3,
kMaxValue = kFederatedConnectionFailedToEstablish
};
// Represents possible states in the example reporting of the federated
// metrics manager itself. These values persist to logs. Entries should not be
// renumbered and numeric values should never be reused.
enum class ReportStatus {
kOk = 0,
kFederatedServiceNotAvailable = 1,
kFederatedServiceNotConnected = 2,
kMaxValue = kFederatedServiceNotConnected
};
FederatedMetricsManager(
ash::AppListNotifier* notifier,
ash::federated::FederatedServiceController* controller);
~FederatedMetricsManager() override;
FederatedMetricsManager(const FederatedMetricsManager&) = delete;
FederatedMetricsManager& operator=(const FederatedMetricsManager&) = delete;
// ash::AppListNotifier::Observer:
// TODO(b/262611120): `FederatedMetricsManager` tracks session-level actions
// by monitoring finer-grained events. Certain orderings of events are assumed
// by `FederatedMetricsManager`, but are not strictly guaranteed by the
// `AppListNotifier`. For example, that `OnLaunch` is followed by
// `OnSearchSessionEnded`. Consider adding new methods to the
// `AppListNotifier` which more directly signal session-level events of
// interest.
void OnSearchSessionStarted() override;
void OnSearchSessionEnded(const std::u16string& query) override;
void OnSeen(Location location,
const std::vector<Result>& results,
const std::u16string& query) override;
void OnLaunch(Location location,
const Result& launched,
const std::vector<Result>& shown,
const std::u16string& query) override;
// Default search engine is one criterion for determining whether logging
// will proceed.
// First called via AppListClientImpl::SetProfile(), and subsequently via
// AppListClientImpl::OnTemplateURLServiceChanged().
void OnDefaultSearchIsGoogleSet(bool is_google);
private:
// Whether the metrics manager is tracking an active search session.
bool session_active_ = false;
// Tracks the metric recorded when EndSearchSession() is called.
ash::SearchSessionConclusion session_result_ =
ash::SearchSessionConclusion::kQuit;
std::optional<bool> is_default_search_engine_google_;
// Note: There's no guarantee that the federated service will stay
// available, so call `IsFederatedServiceAvailable()` before each attempt at
// interacting with the service.
bool IsFederatedServiceAvailable();
bool IsLoggingEnabled();
void TryToBindFederatedServiceIfNecessary();
void LogExample(const std::string& query);
base::ScopedObservation<ash::AppListNotifier, ash::AppListNotifier::Observer>
observation_{this};
mojo::Remote<chromeos::federated::mojom::FederatedService> federated_service_;
const raw_ptr<ash::federated::FederatedServiceController> controller_;
};
} // namespace app_list::federated
#endif // CHROME_BROWSER_ASH_APP_LIST_SEARCH_FEDERATED_METRICS_MANAGER_H_
|