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

Add downloading stage event for force installed extensions

We have several downloading stages that the force installed extension
must go through. We want to add downloading stage event to the
existing events for the event based reporting for force installed
extensions.

Bug: 1108257
Change-Id: I0dacd8f319c1d9eed186fc290d20659c2bbfd223
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2310539
Commit-Queue: Swapnil Gupta <swapnilgupta@google.com>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarOleg Davydov <burunduk@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#793685}
parent 3c53d30e
......@@ -153,6 +153,38 @@ ConvertInstallationStageToProto(extensions::InstallStageTracker::Stage stage) {
}
}
// Helper method to convert ExtensionDownloaderDelegate::Stage to the
// DownloadingStage proto.
em::ExtensionInstallReportLogEvent_DownloadingStage
ConvertDownloadingStageToProto(
extensions::ExtensionDownloaderDelegate::Stage stage) {
using DownloadingStage = extensions::ExtensionDownloaderDelegate::Stage;
switch (stage) {
case DownloadingStage::PENDING:
return em::ExtensionInstallReportLogEvent::DOWNLOAD_PENDING;
case DownloadingStage::QUEUED_FOR_MANIFEST:
return em::ExtensionInstallReportLogEvent::QUEUED_FOR_MANIFEST;
case DownloadingStage::DOWNLOADING_MANIFEST:
return em::ExtensionInstallReportLogEvent::DOWNLOADING_MANIFEST;
case DownloadingStage::DOWNLOADING_MANIFEST_RETRY:
return em::ExtensionInstallReportLogEvent::DOWNLOADING_MANIFEST_RETRY;
case DownloadingStage::PARSING_MANIFEST:
return em::ExtensionInstallReportLogEvent::PARSING_MANIFEST;
case DownloadingStage::MANIFEST_LOADED:
return em::ExtensionInstallReportLogEvent::MANIFEST_LOADED;
case DownloadingStage::QUEUED_FOR_CRX:
return em::ExtensionInstallReportLogEvent::QUEUED_FOR_CRX;
case DownloadingStage::DOWNLOADING_CRX:
return em::ExtensionInstallReportLogEvent::DOWNLOADING_CRX;
case DownloadingStage::DOWNLOADING_CRX_RETRY:
return em::ExtensionInstallReportLogEvent::DOWNLOADING_CRX_RETRY;
case DownloadingStage::FINISHED:
return em::ExtensionInstallReportLogEvent::FINISHED;
default:
NOTREACHED();
}
}
} // namespace
ExtensionInstallEventLogCollector::ExtensionInstallEventLogCollector(
......@@ -248,6 +280,16 @@ void ExtensionInstallEventLogCollector::OnExtensionInstallationStageChanged(
delegate_->Add(id, true /* gather_disk_space_info */, std::move(event));
}
void ExtensionInstallEventLogCollector::OnExtensionDownloadingStageChanged(
const extensions::ExtensionId& id,
extensions::ExtensionDownloaderDelegate::Stage stage) {
if (!delegate_->IsExtensionPending(id))
return;
auto event = std::make_unique<em::ExtensionInstallReportLogEvent>();
event->set_downloading_stage(ConvertDownloadingStageToProto(stage));
delegate_->Add(id, true /* gather_disk_space_info */, std::move(event));
}
void ExtensionInstallEventLogCollector::OnExtensionLoaded(
content::BrowserContext* browser_context,
const extensions::Extension* extension) {
......
......@@ -100,6 +100,9 @@ class ExtensionInstallEventLogCollector
void OnExtensionInstallationStageChanged(
const extensions::ExtensionId& id,
extensions::InstallStageTracker::Stage stage) override;
void OnExtensionDownloadingStageChanged(
const extensions::ExtensionId& id,
extensions::ExtensionDownloaderDelegate::Stage stage) override;
// Reports success events for the extensions which are requested from policy
// and are already loaded.
......
......@@ -420,4 +420,42 @@ TEST_F(ExtensionInstallEventLogCollectorTest, InstallationStageChanged) {
0 /*expected_add_all_count*/));
}
// Verifies that a new event is created when the downloading stage is changed
// during the downloading process.
TEST_F(ExtensionInstallEventLogCollectorTest, DownloadingStageChanged) {
std::unique_ptr<ExtensionInstallEventLogCollector> collector =
std::make_unique<ExtensionInstallEventLogCollector>(
registry(), delegate(), profile());
auto ext = extensions::ExtensionBuilder(kExtensionName1)
.SetID(kExtensionId1)
.Build();
collector->OnExtensionDownloadingStageChanged(
kExtensionId1, extensions::ExtensionDownloaderDelegate::Stage::PENDING);
ASSERT_TRUE(VerifyEventAddedSuccessfully(1 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::DOWNLOAD_PENDING,
delegate()->last_request().event.downloading_stage());
collector->OnExtensionDownloadingStageChanged(
kExtensionId1,
extensions::ExtensionDownloaderDelegate::Stage::DOWNLOADING_MANIFEST);
ASSERT_TRUE(VerifyEventAddedSuccessfully(2 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::DOWNLOADING_MANIFEST,
delegate()->last_request().event.downloading_stage());
collector->OnExtensionDownloadingStageChanged(
kExtensionId1,
extensions::ExtensionDownloaderDelegate::Stage::DOWNLOADING_CRX);
ASSERT_TRUE(VerifyEventAddedSuccessfully(3 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::DOWNLOADING_CRX,
delegate()->last_request().event.downloading_stage());
collector->OnExtensionDownloadingStageChanged(
kExtensionId1, extensions::ExtensionDownloaderDelegate::Stage::FINISHED);
ASSERT_TRUE(VerifyEventAddedSuccessfully(4 /*expected_add_count*/,
0 /*expected_add_all_count*/));
EXPECT_EQ(em::ExtensionInstallReportLogEvent::FINISHED,
delegate()->last_request().event.downloading_stage());
}
} // namespace policy
......@@ -41,6 +41,7 @@ constexpr char kAndroidAppInstallEvent[] = "androidAppInstallEvent";
// Chrome Reporting API.
constexpr char kExtensionId[] = "extensionId";
constexpr char kExtensionInstallEvent[] = "extensionAppInstallEvent";
constexpr char kDownloadStage[] = "downloadStage";
// Calculates hash for the given |event| and |context|, and stores the hash in
// |hash|. Returns true if |event| and |context| are json serializable and
......@@ -159,6 +160,11 @@ base::Value ConvertExtensionEventToValue(
extension_install_report_log_event.session_state_change_type());
}
if (extension_install_report_log_event.has_downloading_stage()) {
event.SetIntKey(kDownloadStage,
extension_install_report_log_event.downloading_stage());
}
event.SetStringKey(kSerialNumber, GetSerialNumber());
base::Value wrapper(base::Value::Type::DICTIONARY);
......
......@@ -152,7 +152,9 @@ void InstallStageTracker::ReportDownloadingStage(
data.download_CRX_started_time = base::Time::Now();
else if (stage == ExtensionDownloaderDelegate::Stage::FINISHED)
data.download_CRX_finish_time = base::Time::Now();
for (auto& observer : observers_) {
observer.OnExtensionDownloadingStageChanged(id, stage);
observer.OnExtensionDataChangedForTesting(id, browser_context_, data);
}
}
......
......@@ -333,6 +333,11 @@ class InstallStageTracker : public KeyedService {
// Called when installation stage of extension is updated.
virtual void OnExtensionInstallationStageChanged(const ExtensionId& id,
Stage stage) {}
// Called when downloading stage of extension is updated.
virtual void OnExtensionDownloadingStageChanged(
const ExtensionId& id,
ExtensionDownloaderDelegate::Stage stage) {}
};
explicit InstallStageTracker(const content::BrowserContext* context);
......
......@@ -2911,6 +2911,32 @@ message ExtensionInstallReportLogEvent {
COMPLETE = 4;
};
// Current stage of the extension downloading process. See
// ExtensionDownloaderDelegate::Stage for more details.
// ExtensionDownloaderDelegate::Stage is the main enum and this is a copy used
// for reporting purposes.
enum DownloadingStage {
DOWNLOAD_PENDING = 0;
QUEUED_FOR_MANIFEST = 1;
DOWNLOADING_MANIFEST = 2;
DOWNLOADING_MANIFEST_RETRY = 3;
PARSING_MANIFEST = 4;
MANIFEST_LOADED = 5;
QUEUED_FOR_CRX = 6;
DOWNLOADING_CRX = 7;
DOWNLOADING_CRX_RETRY = 8;
FINISHED = 9;
};
// Timestamp, in microseconds since epoch. Set for all log
// events.
optional int64 timestamp = 1;
......@@ -2935,6 +2961,9 @@ message ExtensionInstallReportLogEvent {
// Stage of installation process.
optional InstallationStage installation_stage = 8;
// Stage of downloading process.
optional DownloadingStage downloading_stage = 9;
}
// A single entry in the push-install log for an app.
......
......@@ -63,7 +63,10 @@ class ExtensionDownloaderDelegate {
// DOWNLOADING_CRX_RETRY -> DOWNLOADING_CRX -> FINISHED.
// Note: enum used for UMA. Do NOT reorder or remove entries. Don't forget to
// update enums.xml (name: ExtensionInstallationDownloadingStage) when adding
// new entries.
// new entries. Don't forget to update device_management_backend.proto (name:
// ExtensionInstallReportLogEvent::DownloadingStage) when adding new entries.
// Don't forget to update ConvertDownloadingStageToProto method in
// ExtensionInstallEventLogCollector.
enum class Stage {
// Downloader just received extension download request.
PENDING = 0,
......
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