Commit ee9aea4f authored by Swapnil's avatar Swapnil Committed by Commit Bot

Add install creation stage event for force installed extensions

We have several install creation stage that the force installed
extension must go through. We want to add install creation
stage event to the existing events for the event based reporting
for force installed extensions. This is added to investigate
the extensions stuck in CREATED stage.

Bug: 1124808
Change-Id: Ifa20a96f6da2078639e98c85362eb51db707cd06
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2421675Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Reviewed-by: default avatarOleg Davydov <burunduk@chromium.org>
Commit-Queue: Swapnil Gupta <swapnilgupta@google.com>
Cr-Commit-Position: refs/heads/master@{#811178}
parent 6a010201
...@@ -132,8 +132,6 @@ em::ExtensionInstallReportLogEvent_FailureReason ConvertFailureReasonToProto( ...@@ -132,8 +132,6 @@ em::ExtensionInstallReportLogEvent_FailureReason ConvertFailureReasonToProto(
} }
// Helper method to convert InstallStageTracker::Stage to the Stage proto. // Helper method to convert InstallStageTracker::Stage to the Stage proto.
// TODO(crbug/1124808): Add an event for the stages that are used for
// investigating CREATED stage.
em::ExtensionInstallReportLogEvent_InstallationStage em::ExtensionInstallReportLogEvent_InstallationStage
ConvertInstallationStageToProto(extensions::InstallStageTracker::Stage stage) { ConvertInstallationStageToProto(extensions::InstallStageTracker::Stage stage) {
using Stage = extensions::InstallStageTracker::Stage; using Stage = extensions::InstallStageTracker::Stage;
...@@ -216,6 +214,34 @@ ConvertDownloadingStageToProto( ...@@ -216,6 +214,34 @@ ConvertDownloadingStageToProto(
} }
} }
em::ExtensionInstallReportLogEvent_InstallCreationStage
ConvertInstallCreationStageToProto(
extensions::InstallStageTracker::InstallCreationStage stage) {
using Stage = extensions::InstallStageTracker::InstallCreationStage;
switch (stage) {
case Stage::CREATION_INITIATED:
return em::ExtensionInstallReportLogEvent::CREATION_INITIATED;
case Stage::NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_FORCED:
return em::ExtensionInstallReportLogEvent::
NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_FORCED;
case Stage::NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_NOT_FORCED:
return em::ExtensionInstallReportLogEvent::
NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_NOT_FORCED;
case Stage::NOTIFIED_FROM_MANAGEMENT:
return em::ExtensionInstallReportLogEvent::NOTIFIED_FROM_MANAGEMENT;
case Stage::NOTIFIED_FROM_MANAGEMENT_NOT_FORCED:
return em::ExtensionInstallReportLogEvent::
NOTIFIED_FROM_MANAGEMENT_NOT_FORCED;
case Stage::SEEN_BY_POLICY_LOADER:
return em::ExtensionInstallReportLogEvent::SEEN_BY_POLICY_LOADER;
case Stage::SEEN_BY_EXTERNAL_PROVIDER:
return em::ExtensionInstallReportLogEvent::SEEN_BY_EXTERNAL_PROVIDER;
default:
NOTREACHED();
return em::ExtensionInstallReportLogEvent::INSTALL_CREATION_STAGE_UNKNOWN;
}
}
} // namespace } // namespace
ExtensionInstallEventLogCollector::ExtensionInstallEventLogCollector( ExtensionInstallEventLogCollector::ExtensionInstallEventLogCollector(
...@@ -341,6 +367,16 @@ void ExtensionInstallEventLogCollector::OnExtensionDownloadingStageChanged( ...@@ -341,6 +367,16 @@ void ExtensionInstallEventLogCollector::OnExtensionDownloadingStageChanged(
delegate_->Add(id, true /* gather_disk_space_info */, std::move(event)); delegate_->Add(id, true /* gather_disk_space_info */, std::move(event));
} }
void ExtensionInstallEventLogCollector::OnExtensionInstallCreationStageChanged(
const extensions::ExtensionId& id,
extensions::InstallStageTracker::InstallCreationStage stage) {
if (!delegate_->IsExtensionPending(id))
return;
auto event = std::make_unique<em::ExtensionInstallReportLogEvent>();
event->set_install_creation_stage(ConvertInstallCreationStageToProto(stage));
delegate_->Add(id, false /* gather_disk_space_info */, std::move(event));
}
void ExtensionInstallEventLogCollector::OnExtensionLoaded( void ExtensionInstallEventLogCollector::OnExtensionLoaded(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const extensions::Extension* extension) { const extensions::Extension* extension) {
......
...@@ -103,6 +103,9 @@ class ExtensionInstallEventLogCollector ...@@ -103,6 +103,9 @@ class ExtensionInstallEventLogCollector
void OnExtensionDownloadingStageChanged( void OnExtensionDownloadingStageChanged(
const extensions::ExtensionId& id, const extensions::ExtensionId& id,
extensions::ExtensionDownloaderDelegate::Stage stage) override; extensions::ExtensionDownloaderDelegate::Stage stage) override;
void OnExtensionInstallCreationStageChanged(
const extensions::ExtensionId& id,
extensions::InstallStageTracker::InstallCreationStage stage) override;
// Reports success events for the extensions which are requested from policy // Reports success events for the extensions which are requested from policy
// and are already loaded. // and are already loaded.
......
...@@ -565,4 +565,44 @@ TEST_F(ExtensionInstallEventLogCollectorTest, DownloadingStageChanged) { ...@@ -565,4 +565,44 @@ TEST_F(ExtensionInstallEventLogCollectorTest, DownloadingStageChanged) {
delegate()->last_request().event.downloading_stage()); delegate()->last_request().event.downloading_stage());
} }
// Verifies that a new event is created when the install creation stage is
// changed.
TEST_F(ExtensionInstallEventLogCollectorTest, InstallCreationStageChanged) {
std::unique_ptr<ExtensionInstallEventLogCollector> collector =
std::make_unique<ExtensionInstallEventLogCollector>(
registry(), delegate(), profile());
auto ext = extensions::ExtensionBuilder(kExtensionName1)
.SetID(kExtensionId1)
.Build();
collector->OnExtensionInstallCreationStageChanged(
kExtensionId1, extensions::InstallStageTracker::InstallCreationStage::
CREATION_INITIATED);
ASSERT_TRUE(VerifyEventAddedSuccessfully(1 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::CREATION_INITIATED,
delegate()->last_request().event.install_creation_stage());
collector->OnExtensionInstallCreationStageChanged(
kExtensionId1, extensions::InstallStageTracker::InstallCreationStage::
NOTIFIED_FROM_MANAGEMENT);
ASSERT_TRUE(VerifyEventAddedSuccessfully(2 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::NOTIFIED_FROM_MANAGEMENT,
delegate()->last_request().event.install_creation_stage());
collector->OnExtensionInstallCreationStageChanged(
kExtensionId1, extensions::InstallStageTracker::InstallCreationStage::
SEEN_BY_POLICY_LOADER);
ASSERT_TRUE(VerifyEventAddedSuccessfully(3 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::SEEN_BY_POLICY_LOADER,
delegate()->last_request().event.install_creation_stage());
collector->OnExtensionInstallCreationStageChanged(
kExtensionId1, extensions::InstallStageTracker::InstallCreationStage::
SEEN_BY_EXTERNAL_PROVIDER);
ASSERT_TRUE(VerifyEventAddedSuccessfully(4 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::SEEN_BY_EXTERNAL_PROVIDER,
delegate()->last_request().event.install_creation_stage());
}
} // namespace policy } // namespace policy
...@@ -48,6 +48,7 @@ constexpr char kExtensionType[] = "extensionType"; ...@@ -48,6 +48,7 @@ constexpr char kExtensionType[] = "extensionType";
constexpr char kUserType[] = "userType"; constexpr char kUserType[] = "userType";
constexpr char kIsNewUser[] = "isNewUser"; constexpr char kIsNewUser[] = "isNewUser";
constexpr char kIsMisconfigurationFailure[] = "isMisconfigurationFailure"; constexpr char kIsMisconfigurationFailure[] = "isMisconfigurationFailure";
constexpr char kInstallCreationStage[] = "installCreationStage";
// Calculates hash for the given |event| and |context|, and stores the hash in // Calculates hash for the given |event| and |context|, and stores the hash in
// |hash|. Returns true if |event| and |context| are json serializable and // |hash|. Returns true if |event| and |context| are json serializable and
...@@ -201,6 +202,12 @@ base::Value ConvertExtensionEventToValue( ...@@ -201,6 +202,12 @@ base::Value ConvertExtensionEventToValue(
extension_install_report_log_event.is_misconfiguration_failure()); extension_install_report_log_event.is_misconfiguration_failure());
} }
if (extension_install_report_log_event.has_install_creation_stage()) {
event.SetIntKey(
kInstallCreationStage,
extension_install_report_log_event.install_creation_stage());
}
base::Value wrapper(base::Value::Type::DICTIONARY); base::Value wrapper(base::Value::Type::DICTIONARY);
wrapper.SetKey(kExtensionInstallEvent, std::move(event)); wrapper.SetKey(kExtensionInstallEvent, std::move(event));
......
...@@ -155,8 +155,10 @@ void InstallStageTracker::ReportInstallCreationStage( ...@@ -155,8 +155,10 @@ void InstallStageTracker::ReportInstallCreationStage(
InstallCreationStage stage) { InstallCreationStage stage) {
InstallationData& data = installation_data_map_[id]; InstallationData& data = installation_data_map_[id];
data.install_creation_stage = stage; data.install_creation_stage = stage;
for (auto& observer : observers_) for (auto& observer : observers_) {
observer.OnExtensionInstallCreationStageChanged(id, stage);
observer.OnExtensionDataChangedForTesting(id, browser_context_, data); observer.OnExtensionDataChangedForTesting(id, browser_context_, data);
}
} }
void InstallStageTracker::ReportInstallationStage(const ExtensionId& id, void InstallStageTracker::ReportInstallationStage(const ExtensionId& id,
......
...@@ -79,6 +79,12 @@ class InstallStageTracker : public KeyedService { ...@@ -79,6 +79,12 @@ class InstallStageTracker : public KeyedService {
// Intermediate stage of extension installation when the Stage is CREATED. // Intermediate stage of extension installation when the Stage is CREATED.
// TODO(crbug.com/989526): These stages are temporary ones for investigation. // TODO(crbug.com/989526): These stages are temporary ones for investigation.
// Remove them after investigation will complete. // Remove them after investigation will complete.
// Note: enum used for UMA. Do NOT reorder or remove entries. Don't forget to
// update enums.xml (name: InstallCreationStage) when adding new
// entries. Don't forget to update device_management_backend.proto (name:
// ExtensionInstallReportLogEvent::InstallCreationStage) when adding new
// entries. Don't forget to update ConvertInstallCreationStageToProto method
// in ExtensionInstallEventLogCollector.
enum InstallCreationStage { enum InstallCreationStage {
UNKNOWN = 0, UNKNOWN = 0,
...@@ -367,6 +373,11 @@ class InstallStageTracker : public KeyedService { ...@@ -367,6 +373,11 @@ class InstallStageTracker : public KeyedService {
virtual void OnExtensionDownloadingStageChanged( virtual void OnExtensionDownloadingStageChanged(
const ExtensionId& id, const ExtensionId& id,
ExtensionDownloaderDelegate::Stage stage) {} ExtensionDownloaderDelegate::Stage stage) {}
// Called when InstallCreationStage of extension is updated.
virtual void OnExtensionInstallCreationStageChanged(
const ExtensionId& id,
InstallCreationStage stage) {}
}; };
explicit InstallStageTracker(const content::BrowserContext* context); explicit InstallStageTracker(const content::BrowserContext* context);
......
...@@ -3006,6 +3006,28 @@ message ExtensionInstallReportLogEvent { ...@@ -3006,6 +3006,28 @@ message ExtensionInstallReportLogEvent {
FINISHED = 10; FINISHED = 10;
} }
// Current stage of the extension creation process. See
// InstallStageTracker::InstallCreationStage for more details.
// InstallStageTracker::InstallCreationStage is the main enum and this is a
// copy used for reporting purposes.
enum InstallCreationStage {
INSTALL_CREATION_STAGE_UNKNOWN = 0;
CREATION_INITIATED = 1;
NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_FORCED = 2;
NOTIFIED_FROM_MANAGEMENT_INITIAL_CREATION_NOT_FORCED = 3;
NOTIFIED_FROM_MANAGEMENT = 4;
NOTIFIED_FROM_MANAGEMENT_NOT_FORCED = 5;
SEEN_BY_POLICY_LOADER = 6;
SEEN_BY_EXTERNAL_PROVIDER = 7;
}
// Timestamp, in microseconds since epoch. Set for all log // Timestamp, in microseconds since epoch. Set for all log
// events. // events.
optional int64 timestamp = 1; optional int64 timestamp = 1;
...@@ -3047,6 +3069,9 @@ message ExtensionInstallReportLogEvent { ...@@ -3047,6 +3069,9 @@ message ExtensionInstallReportLogEvent {
// Whether the current failure is a admin side miconfiguration failure. Set // Whether the current failure is a admin side miconfiguration failure. Set
// for event type INSTALLATION_FAILED. // for event type INSTALLATION_FAILED.
optional bool is_misconfiguration_failure = 13; optional bool is_misconfiguration_failure = 13;
// Stage of install creation process.
optional InstallCreationStage install_creation_stage = 14;
} }
// A single entry in the push-install log for an app. // A single entry in the push-install log for an app.
......
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