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