Skip to content

Commit

Permalink
[Metrics] Record UMA for number of installed apps and extensions
Browse files Browse the repository at this point in the history
This CL adds 9 UMA histogram metrics for the number of installed apps
and extensions. At most once a day and when the user signs out, the
number of recently used apps is summed up in a snapshot and uploaded
to UMA. This CL also reports the number of installed and enabled
non-component browser extensions and themes, regardless of when they
were last used.

Bug: 1110557
Change-Id: Ia0b7c180581b040fe77929d545ae46383576afca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2350543
Commit-Queue: Toby Huang <tobyhuang@chromium.org>
Reviewed-by: Aga Wronska <agawronska@chromium.org>
Reviewed-by: Karan Bhatia <karandeepb@chromium.org>
Reviewed-by: Brian White <bcwhite@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816870}
  • Loading branch information
Toby Huang authored and Commit Bot committed Oct 14, 2020
1 parent 3e18a15 commit e58c19f
Show file tree
Hide file tree
Showing 12 changed files with 661 additions and 15 deletions.
3 changes: 3 additions & 0 deletions chrome/browser/chromeos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,8 @@ source_set("chromeos") {
"child_accounts/event_based_status_reporting_service_factory.h",
"child_accounts/family_features.cc",
"child_accounts/family_features.h",
"child_accounts/family_user_app_metrics.cc",
"child_accounts/family_user_app_metrics.h",
"child_accounts/family_user_metrics_service.cc",
"child_accounts/family_user_metrics_service.h",
"child_accounts/family_user_metrics_service_factory.cc",
Expand Down Expand Up @@ -3254,6 +3256,7 @@ source_set("unit_tests") {
"certificate_provider/certificate_provider_service_unittest.cc",
"child_accounts/child_user_service_unittest.cc",
"child_accounts/event_based_status_reporting_service_unittest.cc",
"child_accounts/family_user_app_metrics_unittest.cc",
"child_accounts/family_user_metrics_service_unittest.cc",
"child_accounts/family_user_session_metrics_unittest.cc",
"child_accounts/parent_access_code/authenticator_unittest.cc",
Expand Down
156 changes: 156 additions & 0 deletions chrome/browser/chromeos/child_accounts/family_user_app_metrics.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/child_accounts/family_user_app_metrics.h"

#include <memory>

#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/mojom/types.mojom.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/manifest.h"

namespace chromeos {

namespace {
constexpr base::TimeDelta k28Days = base::TimeDelta::FromDays(28);
} // namespace

// static
// UMA metrics for a snapshot count of installed and enabled extensions for a
// given family user.
const char FamilyUserAppMetrics::kInstalledExtensionsCountHistogramName[] =
"FamilyUser.InstalledExtensionsCount";
const char FamilyUserAppMetrics::kEnabledExtensionsCountHistogramName[] =
"FamilyUser.EnabledExtensionsCount";

// UMA metrics for a snapshot count of installed apps for a given family user.
const char FamilyUserAppMetrics::kOtherAppsCountHistogramName[] =
"FamilyUser.OtherAppsCount";
const char FamilyUserAppMetrics::kArcAppsCountHistogramName[] =
"FamilyUser.ArcAppsCount";
const char FamilyUserAppMetrics::kBorealisAppsCountHistogramName[] =
"FamilyUser.BorealisAppsCount";
const char FamilyUserAppMetrics::kCrostiniAppsCountHistogramName[] =
"FamilyUser.CrostiniAppsCount";
const char FamilyUserAppMetrics::kExtensionAppsCountHistogramName[] =
"FamilyUser.ExtensionAppsCount";
const char FamilyUserAppMetrics::kWebAppsCountHistogramName[] =
"FamilyUser.WebAppsCount";
// Sum of the above.
const char FamilyUserAppMetrics::kTotalAppsCountHistogramName[] =
"FamilyUser.TotalAppsCount";

FamilyUserAppMetrics::FamilyUserAppMetrics(Profile* profile)
: extension_registry_(extensions::ExtensionRegistry::Get(profile)),
app_registry_(&apps::AppServiceProxyFactory::GetForProfile(profile)
->AppRegistryCache()) {
DCHECK(extension_registry_);
DCHECK(app_registry_);
}

FamilyUserAppMetrics::~FamilyUserAppMetrics() {
if (on_new_day_) {
RecordInstalledExtensionsCount();
RecordEnabledExtensionsCount();
RecordRecentlyUsedAppsCount();
}
}

void FamilyUserAppMetrics::OnNewDay() {
on_new_day_ = true;
}

void FamilyUserAppMetrics::RecordInstalledExtensionsCount() {
int counter = 0;
std::unique_ptr<extensions::ExtensionSet> all_installed_extensions =
extension_registry_->GenerateInstalledExtensionsSet();
for (const auto& extension : *all_installed_extensions) {
if (extensions::Manifest::IsComponentLocation(extension->location()))
continue;
if (extension->is_extension() || extension->is_theme())
counter++;
}
// If a family user has more than a thousand extensions installed, then that
// count is going into an overflow bucket. We don't expect this scenario to
// happen often.
base::UmaHistogramCounts1000(kInstalledExtensionsCountHistogramName, counter);
}

void FamilyUserAppMetrics::RecordEnabledExtensionsCount() {
int counter = 0;
for (const auto& extension : extension_registry_->enabled_extensions()) {
if (extensions::Manifest::IsComponentLocation(extension->location()))
continue;
if (extension->is_extension() || extension->is_theme())
counter++;
}
// If a family user has more than a thousand extensions enabled, then that
// count is going into an overflow bucket. We don't expect this scenario to
// happen often.
base::UmaHistogramCounts1000(kEnabledExtensionsCountHistogramName, counter);
}

void FamilyUserAppMetrics::RecordRecentlyUsedAppsCount() {
int other_counter, arc_counter, borealis_counter, crostini_counter,
extension_counter, web_counter, total_counter;
other_counter = arc_counter = borealis_counter = crostini_counter =
extension_counter = web_counter = total_counter = 0;
app_registry_->ForEachApp([&other_counter, &arc_counter, &borealis_counter,
&crostini_counter, &extension_counter,
&web_counter,
&total_counter](const apps::AppUpdate& update) {
// Only count apps that have been used recently.
if (base::Time::Now() - update.LastLaunchTime() > k28Days)
return;
switch (update.AppType()) {
case apps::mojom::AppType::kArc:
arc_counter++;
break;
case apps::mojom::AppType::kBorealis:
borealis_counter++;
break;
case apps::mojom::AppType::kCrostini:
crostini_counter++;
break;
case apps::mojom::AppType::kExtension:
// The InstalledExtensionsCount only includes regular browser
// extensions and themes. This counter only includes apps. The two
// counters are mutually exclusive.
extension_counter++;
break;
case apps::mojom::AppType::kWeb:
web_counter++;
break;
default:
// We're not interested in tracking other app types in detail.
other_counter++;
break;
}
total_counter++;
});
// If a family user has more than a thousand apps installed, then that count
// is going into an overflow bucket. We don't expect this scenario to happen
// often.
base::UmaHistogramCounts1000(kOtherAppsCountHistogramName, other_counter);
base::UmaHistogramCounts1000(kArcAppsCountHistogramName, arc_counter);
base::UmaHistogramCounts1000(kBorealisAppsCountHistogramName,
borealis_counter);
base::UmaHistogramCounts1000(kCrostiniAppsCountHistogramName,
crostini_counter);
base::UmaHistogramCounts1000(kExtensionAppsCountHistogramName,
extension_counter);
base::UmaHistogramCounts1000(kWebAppsCountHistogramName, web_counter);
base::UmaHistogramCounts1000(kTotalAppsCountHistogramName, total_counter);
}

} // namespace chromeos
67 changes: 67 additions & 0 deletions chrome/browser/chromeos/child_accounts/family_user_app_metrics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_FAMILY_USER_APP_METRICS_H_
#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_FAMILY_USER_APP_METRICS_H_

#include "chrome/browser/chromeos/child_accounts/family_user_metrics_service.h"

class Profile;

namespace extensions {
class ExtensionRegistry;
} // namespace extensions

namespace apps {
class AppRegistryCache;
} // namespace apps

namespace chromeos {

class FamilyUserAppMetrics : public FamilyUserMetricsService::Observer {
public:
// UMA metrics for a snapshot count of installed and enabled extensions for a
// given family user.
static const char kInstalledExtensionsCountHistogramName[];
static const char kEnabledExtensionsCountHistogramName[];

// UMA metrics for a snapshot count of recently used apps for a given family
// user.
static const char kOtherAppsCountHistogramName[];
static const char kArcAppsCountHistogramName[];
static const char kBorealisAppsCountHistogramName[];
static const char kCrostiniAppsCountHistogramName[];
static const char kExtensionAppsCountHistogramName[];
static const char kWebAppsCountHistogramName[];
// Sum of the above metrics for a given snapshot.
static const char kTotalAppsCountHistogramName[];

explicit FamilyUserAppMetrics(Profile* profile);
FamilyUserAppMetrics(const FamilyUserAppMetrics&) = delete;
FamilyUserAppMetrics& operator=(const FamilyUserAppMetrics&) = delete;
~FamilyUserAppMetrics() override;

private:
// FamilyUserMetricsService::Observer:
void OnNewDay() override;

// Records the number of non-component extensions that the family user has
// installed. This count is a superset of the enabled extensions count.
void RecordInstalledExtensionsCount();

// Records the number of non-component extensions that the family user has
// enabled. This count is a subset of the installed extensions count.
void RecordEnabledExtensionsCount();

// Records the number of apps that the family user has recently used.
void RecordRecentlyUsedAppsCount();

const extensions::ExtensionRegistry* const extension_registry_;
apps::AppRegistryCache* const app_registry_;

bool on_new_day_ = false;
};
} // namespace chromeos

#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_FAMILY_USER_APP_METRICS_H_
Loading

0 comments on commit e58c19f

Please sign in to comment.