Commit 0f06a24f authored by Saurabh Nijhara's avatar Saurabh Nijhara Committed by Commit Bot

Add CRX install error detail event for force installed extensions

We can get different error codes if the extension installation fails
due to crx install error.
We want to add crx install error detail event to the existing events for
the event based reporting for force installed extensions so that these
error codes can be recorded.

Bug: 1048640
Change-Id: I9a984d960c540087e8c211515c944ade444e8374
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2469556
Commit-Queue: Saurabh Nijhara <snijhara@google.com>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarSwapnil Gupta <swapnilgupta@google.com>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#822608}
parent 60ce32c4
...@@ -379,6 +379,73 @@ ConvertUnpackerFailureReasonToProto( ...@@ -379,6 +379,73 @@ ConvertUnpackerFailureReasonToProto(
} }
} }
// Helper function to convert extensions::CrxInstallErrorDetail to the
// ExtensionInstallReportLogEvent::CrxInstallErrorDetail proto.
em::ExtensionInstallReportLogEvent_CrxInstallErrorDetail
ConvertCrxInstallErrorDetailToProto(
extensions::CrxInstallErrorDetail error_detail) {
using Error = extensions::CrxInstallErrorDetail;
switch (error_detail) {
case Error::NONE:
return em::ExtensionInstallReportLogEvent::
CRX_INSTALL_ERROR_DETAIL_UNKNOWN;
case Error::CONVERT_USER_SCRIPT_TO_EXTENSION_FAILED:
return em::ExtensionInstallReportLogEvent::
CONVERT_USER_SCRIPT_TO_EXTENSION_FAILED;
case Error::UNEXPECTED_ID:
return em::ExtensionInstallReportLogEvent::UNEXPECTED_ID;
case Error::UNEXPECTED_VERSION:
return em::ExtensionInstallReportLogEvent::UNEXPECTED_VERSION;
case Error::MISMATCHED_VERSION:
return em::ExtensionInstallReportLogEvent::MISMATCHED_VERSION;
case Error::MANIFEST_INVALID:
return em::ExtensionInstallReportLogEvent::CRX_ERROR_MANIFEST_INVALID;
case Error::INSTALL_NOT_ENABLED:
return em::ExtensionInstallReportLogEvent::INSTALL_NOT_ENABLED;
case Error::OFFSTORE_INSTALL_DISALLOWED:
return em::ExtensionInstallReportLogEvent::OFFSTORE_INSTALL_DISALLOWED;
case Error::INCORRECT_APP_CONTENT_TYPE:
return em::ExtensionInstallReportLogEvent::INCORRECT_APP_CONTENT_TYPE;
case Error::NOT_INSTALLED_FROM_GALLERY:
return em::ExtensionInstallReportLogEvent::NOT_INSTALLED_FROM_GALLERY;
case Error::INCORRECT_INSTALL_HOST:
return em::ExtensionInstallReportLogEvent::INCORRECT_INSTALL_HOST;
case Error::DEPENDENCY_NOT_SHARED_MODULE:
return em::ExtensionInstallReportLogEvent::DEPENDENCY_NOT_SHARED_MODULE;
case Error::DEPENDENCY_OLD_VERSION:
return em::ExtensionInstallReportLogEvent::DEPENDENCY_OLD_VERSION;
case Error::DEPENDENCY_NOT_ALLOWLISTED:
return em::ExtensionInstallReportLogEvent::DEPENDENCY_NOT_ALLOWLISTED;
case Error::UNSUPPORTED_REQUIREMENTS:
return em::ExtensionInstallReportLogEvent::UNSUPPORTED_REQUIREMENTS;
case Error::EXTENSION_IS_BLOCKLISTED:
return em::ExtensionInstallReportLogEvent::EXTENSION_IS_BLOCKLISTED;
case Error::DISALLOWED_BY_POLICY:
return em::ExtensionInstallReportLogEvent::DISALLOWED_BY_POLICY;
case Error::KIOSK_MODE_ONLY:
return em::ExtensionInstallReportLogEvent::KIOSK_MODE_ONLY;
case Error::OVERLAPPING_WEB_EXTENT:
return em::ExtensionInstallReportLogEvent::OVERLAPPING_WEB_EXTENT;
case Error::CANT_DOWNGRADE_VERSION:
return em::ExtensionInstallReportLogEvent::CANT_DOWNGRADE_VERSION;
case Error::MOVE_DIRECTORY_TO_PROFILE_FAILED:
return em::ExtensionInstallReportLogEvent::
MOVE_DIRECTORY_TO_PROFILE_FAILED;
case Error::CANT_LOAD_EXTENSION:
return em::ExtensionInstallReportLogEvent::CANT_LOAD_EXTENSION;
case Error::USER_CANCELED:
return em::ExtensionInstallReportLogEvent::USER_CANCELED;
case Error::USER_ABORTED:
return em::ExtensionInstallReportLogEvent::USER_ABORTED;
case Error::UPDATE_NON_EXISTING_EXTENSION:
return em::ExtensionInstallReportLogEvent::UPDATE_NON_EXISTING_EXTENSION;
default:
NOTREACHED();
return em::ExtensionInstallReportLogEvent::
CRX_INSTALL_ERROR_DETAIL_UNKNOWN;
}
}
// Helper function to convert extensions::ManifestInvalidError to the // Helper function to convert extensions::ManifestInvalidError to the
// ExtensionInstallReportLogEvent::ManifestInvalidError proto. // ExtensionInstallReportLogEvent::ManifestInvalidError proto.
em::ExtensionInstallReportLogEvent_ManifestInvalidError em::ExtensionInstallReportLogEvent_ManifestInvalidError
...@@ -508,6 +575,8 @@ void ExtensionInstallEventLogCollector::OnExtensionInstallationFailed( ...@@ -508,6 +575,8 @@ void ExtensionInstallEventLogCollector::OnExtensionInstallationFailed(
extensions::InstallStageTracker::Get(profile_); extensions::InstallStageTracker::Get(profile_);
extensions::InstallStageTracker::InstallationData data = extensions::InstallStageTracker::InstallationData data =
install_stage_tracker->Get(extension_id); install_stage_tracker->Get(extension_id);
// Extension type is only reported if extension installation failed after the
// unpacking stage.
if (data.extension_type) { if (data.extension_type) {
event->set_extension_type(enterprise_reporting::ConvertExtensionTypeToProto( event->set_extension_type(enterprise_reporting::ConvertExtensionTypeToProto(
data.extension_type.value())); data.extension_type.value()));
...@@ -522,6 +591,13 @@ void ExtensionInstallEventLogCollector::OnExtensionInstallationFailed( ...@@ -522,6 +591,13 @@ void ExtensionInstallEventLogCollector::OnExtensionInstallationFailed(
event->set_manifest_invalid_error(ConvertManifestInvalidErrorToProto( event->set_manifest_invalid_error(ConvertManifestInvalidErrorToProto(
data.manifest_invalid_error.value())); data.manifest_invalid_error.value()));
} }
// Crx install error detail is only reported if extension installation failed
// after the unpacking stage.
if (data.install_error_detail) {
event->set_crx_install_error_detail(
ConvertCrxInstallErrorDetailToProto(data.install_error_detail.value()));
}
extensions::ForceInstalledTracker* force_installed_tracker = extensions::ForceInstalledTracker* force_installed_tracker =
extensions::ExtensionSystem::Get(profile_) extensions::ExtensionSystem::Get(profile_)
->extension_service() ->extension_service()
......
...@@ -52,6 +52,7 @@ constexpr char kInstallCreationStage[] = "installCreationStage"; ...@@ -52,6 +52,7 @@ constexpr char kInstallCreationStage[] = "installCreationStage";
constexpr char kDownloadCacheStatus[] = "downloadCacheStatus"; constexpr char kDownloadCacheStatus[] = "downloadCacheStatus";
constexpr char kUnpackerFailureReason[] = "unpackerFailureReason"; constexpr char kUnpackerFailureReason[] = "unpackerFailureReason";
constexpr char kManifestInvalidError[] = "manifestInvalidError"; constexpr char kManifestInvalidError[] = "manifestInvalidError";
constexpr char kCrxInstallErrorDetail[] = "crxInstallErrorDetail";
// 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
...@@ -228,6 +229,12 @@ base::Value ConvertExtensionEventToValue( ...@@ -228,6 +229,12 @@ base::Value ConvertExtensionEventToValue(
extension_install_report_log_event.manifest_invalid_error()); extension_install_report_log_event.manifest_invalid_error());
} }
if (extension_install_report_log_event.has_crx_install_error_detail()) {
event.SetIntKey(
kCrxInstallErrorDetail,
extension_install_report_log_event.crx_install_error_detail());
}
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));
......
...@@ -51,6 +51,7 @@ constexpr char kInstallCreationStage[] = "installCreationStage"; ...@@ -51,6 +51,7 @@ constexpr char kInstallCreationStage[] = "installCreationStage";
constexpr char kDownloadCacheStatus[] = "downloadCacheStatus"; constexpr char kDownloadCacheStatus[] = "downloadCacheStatus";
constexpr char kUnpackerFailureReason[] = "unpackerFailureReason"; constexpr char kUnpackerFailureReason[] = "unpackerFailureReason";
constexpr char kManifestInvalidError[] = "manifestInvalidError"; constexpr char kManifestInvalidError[] = "manifestInvalidError";
constexpr char kCrxInstallErrorDetail[] = "crxInstallErrorDetail";
void ConvertToValueAndVerify(const em::ExtensionInstallReportLogEvent& event, void ConvertToValueAndVerify(const em::ExtensionInstallReportLogEvent& event,
const std::vector<std::string>& keys) { const std::vector<std::string>& keys) {
...@@ -100,6 +101,25 @@ TEST_F(ExtensionInstallEventLogUtilTest, FailureReasonEvent) { ...@@ -100,6 +101,25 @@ TEST_F(ExtensionInstallEventLogUtilTest, FailureReasonEvent) {
kExtensionType, kStatefulTotal, kStatefulFree}); kExtensionType, kStatefulTotal, kStatefulFree});
} }
// Verifies that an event reporting extension installation failure after
// unpacking is successfully parsed.
TEST_F(ExtensionInstallEventLogUtilTest, CrxInstallErrorEvent) {
event_.set_event_type(
em::ExtensionInstallReportLogEvent::INSTALLATION_FAILED);
event_.set_failure_reason(
em::ExtensionInstallReportLogEvent::CRX_INSTALL_ERROR_OTHER);
event_.set_crx_install_error_detail(
em::ExtensionInstallReportLogEvent::UNEXPECTED_ID);
event_.set_is_misconfiguration_failure(false);
event_.set_extension_type(em::Extension_ExtensionType_TYPE_EXTENSION);
event_.set_stateful_total(kDiskSpaceTotalBytes);
event_.set_stateful_free(kDiskSpaceFreeBytes);
ConvertToValueAndVerify(
event_, {kEventType, kFailureReason, kCrxInstallErrorDetail,
kIsMisconfigurationFailure, kExtensionType, kStatefulTotal,
kStatefulFree});
}
// Verifies that an event reporting extension unpack failure is successfully // Verifies that an event reporting extension unpack failure is successfully
// parsed. // parsed.
TEST_F(ExtensionInstallEventLogUtilTest, UnpackerFailureReasonEvent) { TEST_F(ExtensionInstallEventLogUtilTest, UnpackerFailureReasonEvent) {
......
...@@ -3083,7 +3083,39 @@ message ExtensionInstallReportLogEvent { ...@@ -3083,7 +3083,39 @@ message ExtensionInstallReportLogEvent {
INVALID_VERSION = 12; INVALID_VERSION = 12;
BAD_UPDATE_SPECIFICATION = 13; BAD_UPDATE_SPECIFICATION = 13;
BAD_APP_STATUS = 14; BAD_APP_STATUS = 14;
}; }
// Extended error code if the extension installation failed due to CRX install
// error. See extensions::CrxInstallErrorDetail for more details.
// extensions::CrxInstallErrorDetail is the main enum and this is a
// copy used for reporting purposes.
enum CrxInstallErrorDetail {
CRX_INSTALL_ERROR_DETAIL_UNKNOWN = 0;
CONVERT_USER_SCRIPT_TO_EXTENSION_FAILED = 1;
UNEXPECTED_ID = 2;
UNEXPECTED_VERSION = 3;
MISMATCHED_VERSION = 4;
CRX_ERROR_MANIFEST_INVALID = 5;
INSTALL_NOT_ENABLED = 6;
OFFSTORE_INSTALL_DISALLOWED = 7;
INCORRECT_APP_CONTENT_TYPE = 8;
NOT_INSTALLED_FROM_GALLERY = 9;
INCORRECT_INSTALL_HOST = 10;
DEPENDENCY_NOT_SHARED_MODULE = 11;
DEPENDENCY_OLD_VERSION = 12;
DEPENDENCY_NOT_ALLOWLISTED = 13;
UNSUPPORTED_REQUIREMENTS = 14;
EXTENSION_IS_BLOCKLISTED = 15;
DISALLOWED_BY_POLICY = 16;
KIOSK_MODE_ONLY = 17;
OVERLAPPING_WEB_EXTENT = 18;
CANT_DOWNGRADE_VERSION = 19;
MOVE_DIRECTORY_TO_PROFILE_FAILED = 20;
CANT_LOAD_EXTENSION = 21;
USER_CANCELED = 22;
USER_ABORTED = 23;
UPDATE_NON_EXISTING_EXTENSION = 24;
}
// Timestamp, in microseconds since epoch. Set for all log // Timestamp, in microseconds since epoch. Set for all log
// events. // events.
...@@ -3139,6 +3171,10 @@ message ExtensionInstallReportLogEvent { ...@@ -3139,6 +3171,10 @@ message ExtensionInstallReportLogEvent {
// Detailed reason why extension failed due to failure reason // Detailed reason why extension failed due to failure reason
// MANIFEST_INVALID. // MANIFEST_INVALID.
optional ManifestInvalidError manifest_invalid_error = 17; optional ManifestInvalidError manifest_invalid_error = 17;
// Extended error code if the extension installation failed due to CRX install
// error.
optional CrxInstallErrorDetail crx_install_error_detail = 18;
} }
// A single entry in the push-install log for an app. // A single entry in the push-install log for an app.
......
...@@ -28,7 +28,12 @@ enum class CrxInstallErrorType { ...@@ -28,7 +28,12 @@ enum class CrxInstallErrorType {
// Extended error code that may help explain the error type. // Extended error code that may help explain the error type.
// Do not change the order of the entries or remove entries in this list. // Do not change the order of the entries or remove entries in this list.
// Don't forget to update enums.xml when adding new entries. // 1) Don't forget to update enums.xml when adding new entries.
// 2) Don't forget to update device_management_backend.proto (name:
// ExtensionInstallReportLogEvent::CrxInstallErrorDetail) when adding new
// entries.
// 3) Don't forget to update ConvertCrxInstallErrorDetailToProto method in
// ExtensionInstallEventLogCollector.
enum class CrxInstallErrorDetail { enum class CrxInstallErrorDetail {
NONE, // 0 NONE, // 0
CONVERT_USER_SCRIPT_TO_EXTENSION_FAILED, // 1 CONVERT_USER_SCRIPT_TO_EXTENSION_FAILED, // 1
......
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