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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// Copyright 2021 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_APPS_APP_SERVICE_METRICS_APP_PLATFORM_INPUT_METRICS_H_
#define CHROME_BROWSER_APPS_APP_SERVICE_METRICS_APP_PLATFORM_INPUT_METRICS_H_
#include <map>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/apps/app_service/metrics/app_platform_metrics_utils.h"
#include "chrome/browser/apps/app_service/metrics/browser_to_tab_list.h"
#include "chrome/browser/profiles/profile.h"
#include "components/services/app_service/public/cpp/instance_registry.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/events/event_handler.h"
namespace apps {
class InstanceUpdate;
// This is used for logging, so do not remove or reorder existing entries.
enum class InputEventSource {
kUnknown = 0,
kMouse = 1,
kStylus = 2,
kTouch = 3,
kKeyboard = 4,
// Add any new values above this one, and update kMaxValue to the highest
// enumerator value.
kMaxValue = kKeyboard,
};
extern const char kAppInputEventsKey[];
// This class is used to record the input events for the app windows.
class AppPlatformInputMetrics : public ui::EventHandler,
public InstanceRegistry::Observer,
public ukm::UkmRecorder::Observer {
public:
// For web apps and Chrome apps, there might be different app type name for
// opening in tab or window. So record the app type name for the event count.
using CountPerAppType = base::flat_map<AppTypeName, int>;
// The map to record the event count for each InputEventSource.
using EventSourceToCounts = base::flat_map<InputEventSource, CountPerAppType>;
AppPlatformInputMetrics(Profile* profile,
const apps::AppRegistryCache& app_registry_cache,
InstanceRegistry& instance_registry);
AppPlatformInputMetrics(const AppPlatformInputMetrics&) = delete;
AppPlatformInputMetrics& operator=(const AppPlatformInputMetrics&) = delete;
~AppPlatformInputMetrics() override;
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override;
void OnKeyEvent(ui::KeyEvent* event) override;
void OnTouchEvent(ui::TouchEvent* event) override;
void OnFiveMinutes();
// Records the input events AppKM each 2 hours.
void OnTwoHours();
private:
struct AppInfo {
std::string app_id;
AppTypeName app_type_name;
};
// InstanceRegistry::Observer:
void OnInstanceUpdate(const InstanceUpdate& update) override;
void OnInstanceRegistryWillBeDestroyed(InstanceRegistry* cache) override;
// ukm::UkmRecorder::Observer:
// Called only in Managed Guest Session since the observation is started only
// in Managed Guest Session.
void OnStartingShutdown() override;
void SetAppInfoForActivatedWindow(AppType app_type,
const std::string& app_id,
aura::Window* window,
const base::UnguessableToken& instance_id);
void SetAppInfoForInactivatedWindow(
const base::UnguessableToken& instance_id);
void RecordEventCount(InputEventSource event_source,
ui::EventTarget* event_target);
ukm::SourceId GetSourceId(const std::string& app_id);
void RecordInputEventsAppKM();
void RecordInputEventsAppKMForApp(const std::string& app_id,
const EventSourceToCounts& event_counts);
// Saves the input events in `app_id_to_event_count_per_two_hours_` to the
// user pref each 2 hours. For example:
// web_app_id1: {
// mouse: { ChromeBrowser: 5, WebApp: 2}
// keyboard: { ChromeBrowser: 2, WebApp: 3}
// },
// chrome_app_id2: {
// stylus: { ChromeBrowser: 2, ChromeApp: 12}
// keyboard: { ChromeBrowser: 3, ChromeApp: 30}
// },
// Arc_app_id3: {
// mouse: { Arc: 5}
// },
void SaveInputEvents();
// Records the input events AppKM saved in the user pref.
void RecordInputEventsAppKMFromPref();
// Returns true if recording is allowed for this app.
bool ShouldRecordAppKMForApp(const std::string& app_id);
raw_ptr<Profile> profile_;
const raw_ref<const AppRegistryCache> app_registry_cache_;
BrowserToTabList browser_to_tab_list_;
bool should_record_ukm_from_pref_ = true;
// The map from the window to the app info.
base::flat_map<aura::Window*, AppInfo> window_to_app_info_;
// Records the input even count for each app id in the past five minutes. Each
// app id might have multiple events. For web apps and Chrome apps, there
// might be different app type name, e.g. Chrome browser for apps opening in
// a tab, or Web app for apps opening in a window. For example:
// web_app_id1: {
// mouse: { Chrome browser: 5, Web app: 2}
// Keyboard: { Chrome browser: 2, Web app: 3}
// },
// chrome_app_id2: {
// stylus: { Chrome browser: 2, Chrome app: 12}
// Keyboard: { Chrome browser: 3, Chrome app: 30}
// },
// Arc_app_id3: {
// mouse: { Arc: 5}
// },
std::map<std::string, EventSourceToCounts>
app_id_to_event_count_per_two_hours_;
base::ScopedObservation<InstanceRegistry, InstanceRegistry::Observer>
instance_registry_observation_{this};
// Observes `UkmRecorder` only in Managed Guest Session.
base::ScopedObservation<ukm::UkmRecorder, ukm::UkmRecorder::Observer>
ukm_recorder_observer_{this};
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_APP_SERVICE_METRICS_APP_PLATFORM_INPUT_METRICS_H_
|