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
ash / components / arc / metrics / stability_metrics_manager.cc [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/components/arc/metrics/stability_metrics_manager.h"
#include <ostream>
#include "ash/components/arc/arc_prefs.h"
#include "base/metrics/histogram_macros.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
namespace arc {
namespace {
constexpr char kArcEnabledStateKey[] = "enabled_state";
constexpr char kArcNativeBridgeTypeKey[] = "native_bridge_type";
StabilityMetricsManager* g_stability_metrics_manager = nullptr;
} // namespace
// static
void StabilityMetricsManager::Initialize(PrefService* local_state) {
DCHECK(!g_stability_metrics_manager);
g_stability_metrics_manager = new StabilityMetricsManager(local_state);
}
// static
void StabilityMetricsManager::Shutdown() {
DCHECK(g_stability_metrics_manager);
delete g_stability_metrics_manager;
g_stability_metrics_manager = nullptr;
}
// static
StabilityMetricsManager* StabilityMetricsManager::Get() {
return g_stability_metrics_manager;
}
StabilityMetricsManager::StabilityMetricsManager(PrefService* local_state)
: local_state_(local_state) {}
StabilityMetricsManager::~StabilityMetricsManager() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
void StabilityMetricsManager::RecordMetricsToUMA() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// FindPreference(prefs::kStabilityMetrics) should never return null, but
// since this may be called early on browser startup, be paranoid here to
// prevent going into a crash loop.
if (const auto* pref = local_state_->FindPreference(prefs::kStabilityMetrics);
!pref || pref->GetType() != base::Value::Type::DICT) {
NOTREACHED() << "Local state unavailable, not recording stability metrics.";
}
const std::optional<bool> enabled_state = GetArcEnabledState();
if (enabled_state)
UMA_STABILITY_HISTOGRAM_ENUMERATION("Arc.State", *enabled_state ? 1 : 0, 2);
const std::optional<NativeBridgeType> native_bridge_type =
GetArcNativeBridgeType();
if (native_bridge_type) {
UMA_STABILITY_HISTOGRAM_ENUMERATION(
"Arc.NativeBridge", *native_bridge_type,
static_cast<int>(NativeBridgeType::kMaxValue) + 1);
}
}
void StabilityMetricsManager::ResetMetrics() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
local_state_->SetDict(prefs::kStabilityMetrics, base::Value::Dict());
}
std::optional<bool> StabilityMetricsManager::GetArcEnabledState() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const base::Value::Dict& dict =
local_state_->GetDict(prefs::kStabilityMetrics);
return dict.FindBool(kArcEnabledStateKey);
}
void StabilityMetricsManager::SetArcEnabledState(bool enabled) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ScopedDictPrefUpdate update(local_state_, prefs::kStabilityMetrics);
update->Set(kArcEnabledStateKey, enabled);
}
std::optional<NativeBridgeType>
StabilityMetricsManager::GetArcNativeBridgeType() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const base::Value::Dict& dict =
local_state_->GetDict(prefs::kStabilityMetrics);
std::optional<int> native_bridge_type = dict.FindInt(kArcNativeBridgeTypeKey);
if (native_bridge_type) {
return std::make_optional(
static_cast<NativeBridgeType>(*native_bridge_type));
}
return std::nullopt;
}
void StabilityMetricsManager::SetArcNativeBridgeType(
NativeBridgeType native_bridge_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ScopedDictPrefUpdate update(local_state_, prefs::kStabilityMetrics);
update->Set(kArcNativeBridgeTypeKey, static_cast<int>(native_bridge_type));
}
} // namespace arc