Commit 9944b6e5 authored by Devlin Cronin's avatar Devlin Cronin Committed by Commit Bot

[Extensions][Metrics] Add and use extension_install.proto

Add and use an extension_install.proto file. This will allow us to
gather more detailed metrics on the types of extensions that users
have installed, and determine the answers to more structured queries
than could be determined by UMA histograms alone.

Add the extension_install.proto and an ExtensionInstallMetricsProvider
to gather these metrics, and hook these up to the metrics service.

Add unittests for the provider.

Bug: 673875
Change-Id: Ic0bdded27cafe3de75f2edeec2e7d927e0e2ecb6
Reviewed-on: https://chromium-review.googlesource.com/621672
Commit-Queue: Devlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarIlya Sherman <isherman@chromium.org>
Reviewed-by: default avatarMark Pearson <mpearson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505259}
parent 334ba250
...@@ -9,13 +9,18 @@ ...@@ -9,13 +9,18 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "base/time/time.h"
#include "components/metrics/metrics_provider.h" #include "components/metrics/metrics_provider.h"
#include "components/metrics/proto/extension_install.pb.h"
class Profile; class Profile;
namespace extensions { namespace extensions {
class Extension;
class ExtensionPrefs;
class ExtensionSet; class ExtensionSet;
} }
...@@ -39,6 +44,14 @@ class ExtensionsMetricsProvider : public metrics::MetricsProvider { ...@@ -39,6 +44,14 @@ class ExtensionsMetricsProvider : public metrics::MetricsProvider {
void ProvideSystemProfileMetrics( void ProvideSystemProfileMetrics(
metrics::SystemProfileProto* system_profile) override; metrics::SystemProfileProto* system_profile) override;
static metrics::ExtensionInstallProto ConstructInstallProtoForTesting(
const extensions::Extension& extension,
extensions::ExtensionPrefs* prefs,
base::Time last_sample_time);
static std::vector<metrics::ExtensionInstallProto>
GetInstallsForProfileForTesting(Profile* profile,
base::Time last_sample_time);
protected: protected:
// Exposed for the sake of mocking in test code. // Exposed for the sake of mocking in test code.
...@@ -68,6 +81,11 @@ class ExtensionsMetricsProvider : public metrics::MetricsProvider { ...@@ -68,6 +81,11 @@ class ExtensionsMetricsProvider : public metrics::MetricsProvider {
// SystemProfileProto object. // SystemProfileProto object.
void ProvideOccupiedBucketMetric(metrics::SystemProfileProto* system_profile); void ProvideOccupiedBucketMetric(metrics::SystemProfileProto* system_profile);
// Writes information about the installed extensions for all profiles into
// the proto.
void ProvideExtensionInstallsMetrics(
metrics::SystemProfileProto* system_profile);
// The MetricsStateManager from which the client ID is obtained. // The MetricsStateManager from which the client ID is obtained.
metrics::MetricsStateManager* metrics_state_manager_; metrics::MetricsStateManager* metrics_state_manager_;
...@@ -76,6 +94,9 @@ class ExtensionsMetricsProvider : public metrics::MetricsProvider { ...@@ -76,6 +94,9 @@ class ExtensionsMetricsProvider : public metrics::MetricsProvider {
// GetMetricsProfile() can return a consistent value. // GetMetricsProfile() can return a consistent value.
Profile* cached_profile_; Profile* cached_profile_;
// The time of our last recorded sample.
base::Time last_sample_time_;
DISALLOW_COPY_AND_ASSIGN(ExtensionsMetricsProvider); DISALLOW_COPY_AND_ASSIGN(ExtensionsMetricsProvider);
}; };
......
...@@ -10,6 +10,7 @@ proto_library("proto") { ...@@ -10,6 +10,7 @@ proto_library("proto") {
"cast_logs.proto", "cast_logs.proto",
"chrome_user_metrics_extension.proto", "chrome_user_metrics_extension.proto",
"execution_context.proto", "execution_context.proto",
"extension_install.proto",
"histogram_event.proto", "histogram_event.proto",
"memory_leak_report.proto", "memory_leak_report.proto",
"omnibox_event.proto", "omnibox_event.proto",
......
// Copyright 2017 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.
//
// Stores information about an extension installed on a user's machine.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
option java_outer_classname = "ExtensionInstallProtos";
option java_package = "org.chromium.components.metrics";
package metrics;
// Next tag: 16.
message ExtensionInstallProto {
// The type of extension item this is.
enum Type {
UNKNOWN_TYPE = 0; // Unknown (hopefully never used)
EXTENSION = 1; // A browser extension
THEME = 2; // A browser theme
USER_SCRIPT = 3; // An extension converted from a user script
HOSTED_APP = 4; // A hosted app
LEGACY_PACKAGED_APP = 5; // A (deprecated) v1 packaged app
PLATFORM_APP = 6; // A platform app
SHARED_MODULE = 7; // A shared module
}
optional Type type = 1;
// The source of the extension.
enum InstallLocation {
UNKNOWN_LOCATION = 0; // Unknown (hopefully never used)
INTERNAL = 1; // A crx file from the internal Extensions directory; most
// webstore-installed extensions fall into this category.
EXTERNAL_PREF = 2; // A crx file from an external directory (via prefs).
EXTERNAL_REGISTRY = 3; // A crx file from an external directory (via the
// Windows registry)
UNPACKED = 4; // An unpacked extension loaded from chrome://extensions.
COMPONENT = 5; // An internal component extension.
EXTERNAL_PREF_DOWNLOAD = 6; // A crx file from an external directory (via
// prefs), downloaded from an update URL.
EXTERNAL_POLICY_DOWNLOAD = 7; // A crx file from an external directory (via
// admin policies), downloaded from an update
// URL.
COMMAND_LINE = 8; // Loaded from the commandline (e.g. --load-extension).
EXTERNAL_POLICY = 9; // A crx file from an external directory (via admin
// policies), cached locally and installed from the
// cache.
EXTERNAL_COMPONENT = 10; // A component extension that was downloaded
// externally via an update url.
}
optional InstallLocation install_location = 2;
// The manifest version in the extension. Note: this refers to the
// Chrome-required versioning of the manifest, not the extension version.
// Currently, it is always 1 or 2.
optional int32 manifest_version = 3;
// The associated UI action in the extension. Each extension can have at most
// one type of action.
enum ActionType {
NO_ACTION = 0;
BROWSER_ACTION = 1;
PAGE_ACTION = 2;
SYSTEM_INDICATOR = 3;
}
optional ActionType action_type = 4;
// If the extension has been granted file access.
optional bool has_file_access = 5;
// If the extension has been granted permission to run in incognito contexts.
optional bool has_incognito_access = 6;
// If the extension originated from the Chrome Web Store according to the
// prefs.
// This differs from install_location, which specifies from where the location
// on the user’s machine from where the install originated, but not whether
// the extension is hosted in the store. For instance, sideloaded extensions
// that are specified via ID in the registry are downloaded from the store.
optional bool is_from_store = 7;
// If the extension automatically updates from the Chrome Web Store.
optional bool updates_from_store = 8;
// If the extension is a bookmark app that was generated from a web page. This
// is distinct from install_location above, which specifies from where on the
// user’s machine the install originated.
optional bool is_from_bookmark = 9;
// If the extension was created from a user script. This is distinct from
// install_location above, which specifies from where on the user’s machine
// the install originated.
optional bool is_converted_from_user_script = 10;
// If the extension was installed by default when the profile was created.
// These extensions are specified by Chrome.
optional bool is_default_installed = 11;
// If the extension was installed by an OEM. This differs from
// "is_default_installed", since these extensions are specified by the OEM
// rather than by Chrome. These are specified in a file that is created as
// part of the creation of the Chrome image, and can be specific to different
// OEMs.
optional bool is_oem_installed = 12;
// The type of background page this extension has. Each extension can have at
// most one type of background presence.
enum BackgroundScriptType {
NO_BACKGROUND_SCRIPT = 0; // The extension has no background page.
PERSISTENT_BACKGROUND_PAGE = 1; // The extension has a persistent
// background page.
EVENT_PAGE = 2; // The extension has a (lazy) event page.
}
optional BackgroundScriptType background_script_type = 13;
// The reasons an extension may be disabled.
enum DisableReason {
USER_ACTION = 0; // The user disabled the extension.
PERMISSIONS_INCREASE = 1; // The extension increased permissions.
RELOAD = 2; // The extension is reloading.
UNSUPPORTED_REQUIREMENT = 3; // The extension has requirements that weren't
// met (e.g. graphics capabilities).
SIDELOAD_WIPEOUT = 4; // The extension was disabled in the sideload
// wipeout.
UNKNOWN_FROM_SYNC = 5; // The extension was disabled by sync.
NOT_VERIFIED = 6; // The extension couldn't be verified.
GREYLIST = 7; // The extension was found on the greylist.
CORRUPTED = 8; // The extension install was corrupted according to content
// verification.
REMOTE_INSTALL = 9; // The extension was installed remotely and hasn't been
// enabled.
EXTERNAL_EXTENSION = 10; // The extension was sideloaded and hasn't been
// enabled.
UPDATE_REQUIRED_BY_POLICY = 11; // Policy requires an unmet minimum
// version.
CUSTODIAN_APPROVAL_REQUIRED = 12; // The extension is pending custodian
// approval for a supervised user.
BLOCKED_BY_POLICY = 13; // The extension is disabled because it's blocked
// by enterprise policy.
}
// Any DisableReasons in effect for the extension. An empty list means the
// extension is not disabled. Note that an extension that is not disabled may
// nonetheless not be running, e.g., terminated because the extension process
// was killed.
repeated DisableReason disable_reasons = 14;
// The state of the extension in the safe browsing blacklist.
// The numeric values here match the values of the respective enum in
// ClientCRXListInfoResponse proto.
enum BlacklistState {
// The extension is not in the blacklist.
NOT_BLACKLISTED = 0;
// The extension is malware.
BLACKLISTED_MALWARE = 1;
// The extension has a serious security vulnerability.
BLACKLISTED_SECURITY_VULNERABILITY = 2;
// The extension violated CWS policy.
BLACKLISTED_CWS_POLICY_VIOLATION = 3;
// The extension is considered potentially unwanted.
BLACKLISTED_POTENTIALLY_UNWANTED = 4;
// Used when we couldn't connect to server, e.g. when offline.
BLACKLISTED_UNKNOWN = 5;
}
optional BlacklistState blacklist_state = 15;
// Whether the extension was installed in the current sampling period. This
// is useful if trying to use extension installation in conjunction with other
// metrics (e.g. page load). Since some of the metrics from this period will
// have the extension installed and others won't, these records can be
// discarded for that analysis.
optional bool installed_in_this_sample_period = 16;
}
...@@ -13,7 +13,9 @@ option java_package = "org.chromium.components.metrics"; ...@@ -13,7 +13,9 @@ option java_package = "org.chromium.components.metrics";
package metrics; package metrics;
// Next tag: 24 import "extension_install.proto";
// Next tag: 26
message SystemProfileProto { message SystemProfileProto {
// The time when the client was compiled/linked, in seconds since the epoch. // The time when the client was compiled/linked, in seconds since the epoch.
optional int64 build_timestamp = 1; optional int64 build_timestamp = 1;
...@@ -944,4 +946,9 @@ message SystemProfileProto { ...@@ -944,4 +946,9 @@ message SystemProfileProto {
optional fixed32 omaha_fingerprint = 3; optional fixed32 omaha_fingerprint = 3;
} }
repeated ChromeComponent chrome_component = 24; repeated ChromeComponent chrome_component = 24;
// Information about the user's installed extensions. This will include
// extensions from all fully-initialized profiles. If a single extension is
// installed in multiple profiles, it will be recorded multiple times.
repeated ExtensionInstallProto extension_install = 25;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment