Commit 7074f2c6 authored by Swapnil's avatar Swapnil Committed by Commit Bot

Add classes ExtensionInstallEventLog and SingleExtensionInstallEventLog

ArcAppInstallEventLog and SingleArcAppInstallEventLog classes are used
for storing logs on the disk and prepare for upload. Similar classes
are implemented for extension events. ArcAppInstallEventLog::Load
method is refactored to extract the common code into
SingleInstallEventLog class.

Bug: 1081192
Change-Id: I20731598f52d37cc0c890b5254011787f04ff97d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2199282Reviewed-by: default avatarOleg Davydov <burunduk@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Commit-Queue: Swapnil Gupta <swapnilgupta@google.com>
Cr-Commit-Position: refs/heads/master@{#776913}
parent febd5685
...@@ -1942,6 +1942,8 @@ source_set("chromeos") { ...@@ -1942,6 +1942,8 @@ source_set("chromeos") {
"policy/enrollment_handler_chromeos.h", "policy/enrollment_handler_chromeos.h",
"policy/enrollment_requisition_manager.cc", "policy/enrollment_requisition_manager.cc",
"policy/enrollment_requisition_manager.h", "policy/enrollment_requisition_manager.h",
"policy/extension_install_event_log.cc",
"policy/extension_install_event_log.h",
"policy/extension_install_event_log_collector.cc", "policy/extension_install_event_log_collector.cc",
"policy/extension_install_event_log_collector.h", "policy/extension_install_event_log_collector.h",
"policy/extension_install_event_logger.cc", "policy/extension_install_event_logger.cc",
...@@ -2053,6 +2055,8 @@ source_set("chromeos") { ...@@ -2053,6 +2055,8 @@ source_set("chromeos") {
"policy/server_backed_state_keys_broker.h", "policy/server_backed_state_keys_broker.h",
"policy/single_arc_app_install_event_log.cc", "policy/single_arc_app_install_event_log.cc",
"policy/single_arc_app_install_event_log.h", "policy/single_arc_app_install_event_log.h",
"policy/single_extension_install_event_log.cc",
"policy/single_extension_install_event_log.h",
"policy/single_install_event_log.h", "policy/single_install_event_log.h",
"policy/status_collector/activity_storage.cc", "policy/status_collector/activity_storage.cc",
"policy/status_collector/activity_storage.h", "policy/status_collector/activity_storage.h",
......
// 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/policy/extension_install_event_log.h"
namespace em = enterprise_management;
namespace policy {
ExtensionInstallEventLog::ExtensionInstallEventLog(
const base::FilePath& file_name)
: InstallEventLog(file_name) {}
ExtensionInstallEventLog::~ExtensionInstallEventLog() = default;
void ExtensionInstallEventLog::Serialize(
em::ExtensionInstallReportRequest* report) {
report->Clear();
for (const auto& log : logs_) {
em::ExtensionInstallReport* const report_log =
report->add_extension_install_reports();
log.second->Serialize(report_log);
}
}
} // namespace policy
// 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_POLICY_EXTENSION_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_EXTENSION_INSTALL_EVENT_LOG_H_
#include "chrome/browser/chromeos/policy/install_event_log.h"
#include "chrome/browser/chromeos/policy/single_extension_install_event_log.h"
#include "components/policy/proto/device_management_backend.pb.h"
namespace base {
class FilePath;
} // namespace base
namespace policy {
// An event log for extension installs.
class ExtensionInstallEventLog
: public InstallEventLog<
enterprise_management::ExtensionInstallReportLogEvent,
SingleExtensionInstallEventLog> {
public:
explicit ExtensionInstallEventLog(const base::FilePath& file_name);
~ExtensionInstallEventLog();
// Serializes the log to a protobuf for upload to a server. Records which
// entries were serialized so that they may be cleared after successful
// upload.
void Serialize(enterprise_management::ExtensionInstallReportRequest* report);
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_EXTENSION_INSTALL_EVENT_LOG_H_
...@@ -21,68 +21,15 @@ bool SingleArcAppInstallEventLog::Load( ...@@ -21,68 +21,15 @@ bool SingleArcAppInstallEventLog::Load(
std::unique_ptr<SingleArcAppInstallEventLog>* log) { std::unique_ptr<SingleArcAppInstallEventLog>* log) {
log->reset(); log->reset();
if (!file->IsValid()) {
return false;
}
ssize_t size; ssize_t size;
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&size), sizeof(size)) != std::unique_ptr<char[]> package_buffer;
sizeof(size) || if (!ParseIdFromFile(file, &size, &package_buffer))
size > kMaxBufferSize) {
return false; return false;
}
std::unique_ptr<char[]> package_buffer = std::make_unique<char[]>(size);
if (file->ReadAtCurrentPos(package_buffer.get(), size) != size) {
return false;
}
*log = std::make_unique<SingleArcAppInstallEventLog>( *log = std::make_unique<SingleArcAppInstallEventLog>(
std::string(package_buffer.get(), size)); std::string(package_buffer.get(), size));
int64_t incomplete; return LoadEventLogFromFile(file, (*log).get());
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&incomplete),
sizeof(incomplete)) != sizeof(incomplete)) {
return false;
}
(*log)->incomplete_ = incomplete;
ssize_t entries;
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&entries),
sizeof(entries)) != sizeof(entries)) {
return false;
}
for (ssize_t i = 0; i < entries; ++i) {
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&size), sizeof(size)) !=
sizeof(size) ||
size > kMaxBufferSize) {
(*log)->incomplete_ = true;
return false;
}
if (size == 0) {
// Zero-size entries are written if serialization of a log entry fails.
// Skip these on read.
(*log)->incomplete_ = true;
continue;
}
std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size);
if (file->ReadAtCurrentPos(buffer.get(), size) != size) {
(*log)->incomplete_ = true;
return false;
}
em::AppInstallReportLogEvent event;
if (event.ParseFromArray(buffer.get(), size)) {
(*log)->Add(event);
} else {
(*log)->incomplete_ = true;
}
}
return true;
} }
void SingleArcAppInstallEventLog::Serialize(em::AppInstallReport* report) { void SingleArcAppInstallEventLog::Serialize(em::AppInstallReport* report) {
......
...@@ -27,9 +27,10 @@ class SingleArcAppInstallEventLog ...@@ -27,9 +27,10 @@ class SingleArcAppInstallEventLog
// Restores the event log from |file| into |log|. Returns |true| if the // Restores the event log from |file| into |log|. Returns |true| if the
// self-delimiting format of the log was parsed successfully and further logs // self-delimiting format of the log was parsed successfully and further logs
// stored in the file may be loaded. // stored in the file may be loaded.
// |incomplete_| is set to |true| if it was set when storing the log to the // |InstallEventLog::incomplete_| is set to |true| if it was set when storing
// file, the buffer wraps around or any log entries cannot be fully parsed. If // the log to the file, the buffer wraps around or any log entries cannot be
// not even the app name can be parsed, |log| is set to |nullptr|. // fully parsed. If not even the app name can be parsed, |log| is set to
// |nullptr|.
static bool Load(base::File* file, static bool Load(base::File* file,
std::unique_ptr<SingleArcAppInstallEventLog>* log); std::unique_ptr<SingleArcAppInstallEventLog>* log);
......
// 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/policy/single_extension_install_event_log.h"
#include "base/files/file.h"
namespace em = enterprise_management;
namespace policy {
SingleExtensionInstallEventLog::SingleExtensionInstallEventLog(
const std::string& extension_id)
: SingleInstallEventLog(extension_id) {}
SingleExtensionInstallEventLog::~SingleExtensionInstallEventLog() {}
bool SingleExtensionInstallEventLog::Load(
base::File* file,
std::unique_ptr<SingleExtensionInstallEventLog>* log) {
log->reset();
ssize_t size;
std::unique_ptr<char[]> package_buffer;
if (!ParseIdFromFile(file, &size, &package_buffer))
return false;
*log = std::make_unique<SingleExtensionInstallEventLog>(
std::string(package_buffer.get(), size));
return LoadEventLogFromFile(file, (*log).get());
}
void SingleExtensionInstallEventLog::Serialize(
em::ExtensionInstallReport* report) {
report->Clear();
report->set_extension_id(id_);
report->set_incomplete(incomplete_);
for (const auto& event : events_) {
em::ExtensionInstallReportLogEvent* const log_event = report->add_logs();
*log_event = event;
}
serialized_entries_ = events_.size();
}
} // namespace policy
// 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_POLICY_SINGLE_EXTENSION_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_EXTENSION_INSTALL_EVENT_LOG_H_
#include <memory>
#include <string>
#include "chrome/browser/chromeos/policy/single_install_event_log.h"
#include "components/policy/proto/device_management_backend.pb.h"
namespace base {
class File;
}
namespace policy {
// An event log for a single extension's install process.
class SingleExtensionInstallEventLog
: public SingleInstallEventLog<
enterprise_management::ExtensionInstallReportLogEvent> {
public:
explicit SingleExtensionInstallEventLog(const std::string& extension_id);
~SingleExtensionInstallEventLog();
// Restores the event log from |file| into |log|. If not even the extension
// name can be parsed, |log| is set to nullptr and false returned.
// |InstallEventLog::incomplete_| is set to |true| if it was set when storing
// the log to the file. If the event log exceeds the size buffer,
// |log| is created with |InstallEventLog::incomplete_| set to true, and false
// is returned. Otherwise true is returned and if the buffer wraps around or
// any log entries cannot be fully parsed, |InstallEventLog::incomplete_| is
// set to true.
static bool Load(base::File* file,
std::unique_ptr<SingleExtensionInstallEventLog>* log);
// Serializes the log to a protobuf for upload to a server. Records which
// entries were serialized so that they may be cleared after successful
// upload.
void Serialize(enterprise_management::ExtensionInstallReport* report);
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_EXTENSION_INSTALL_EVENT_LOG_H_
...@@ -50,6 +50,18 @@ class SingleInstallEventLog { ...@@ -50,6 +50,18 @@ class SingleInstallEventLog {
static const int kMaxBufferSize = 65536; static const int kMaxBufferSize = 65536;
protected: protected:
// Tries to parse the app name. Returns true if parsing app name is
// successful.
static bool ParseIdFromFile(base::File* file,
ssize_t* size,
std::unique_ptr<char[]>* package_buffer);
// Restores the event log from |file| into |log|. Returns |true| if the
// self-delimiting format of the log was parsed successfully and further logs
// stored in the file may be loaded.
static bool LoadEventLogFromFile(base::File* file,
SingleInstallEventLog<T>* log);
// The app this event log pertains to. // The app this event log pertains to.
const std::string id_; const std::string id_;
...@@ -154,6 +166,73 @@ void SingleInstallEventLog<T>::ClearSerialized() { ...@@ -154,6 +166,73 @@ void SingleInstallEventLog<T>::ClearSerialized() {
incomplete_ = false; incomplete_ = false;
} }
template <typename T>
bool SingleInstallEventLog<T>::ParseIdFromFile(
base::File* file,
ssize_t* size,
std::unique_ptr<char[]>* package_buffer) {
if (!file->IsValid())
return false;
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(size), sizeof(*size)) !=
sizeof(*size) ||
*size > kMaxBufferSize) {
return false;
}
*package_buffer = std::make_unique<char[]>(*size);
if (file->ReadAtCurrentPos((*package_buffer).get(), *size) != *size)
return false;
return true;
}
template <typename T>
bool SingleInstallEventLog<T>::LoadEventLogFromFile(
base::File* file,
SingleInstallEventLog<T>* log) {
int64_t incomplete;
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&incomplete),
sizeof(incomplete)) != sizeof(incomplete)) {
return false;
}
log->incomplete_ = incomplete;
ssize_t entries;
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&entries),
sizeof(entries)) != sizeof(entries)) {
return false;
}
for (ssize_t i = 0; i < entries; ++i) {
ssize_t size;
if (file->ReadAtCurrentPos(reinterpret_cast<char*>(&size), sizeof(size)) !=
sizeof(size) ||
size > kMaxBufferSize) {
log->incomplete_ = true;
return false;
}
if (size == 0) {
// Zero-size entries are written if serialization of a log entry fails.
// Skip these on read.
log->incomplete_ = true;
continue;
}
std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size);
if (file->ReadAtCurrentPos(buffer.get(), size) != size) {
log->incomplete_ = true;
return false;
}
T event;
if (event.ParseFromArray(buffer.get(), size)) {
log->Add(event);
} else {
log->incomplete_ = true;
}
}
return true;
}
} // namespace policy } // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_INSTALL_EVENT_LOG_H_ #endif // CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_INSTALL_EVENT_LOG_H_
...@@ -2786,7 +2786,7 @@ message AppInstallReportLogEvent { ...@@ -2786,7 +2786,7 @@ message AppInstallReportLogEvent {
optional int64 android_id = 9; optional int64 android_id = 9;
} }
// Log bucket for an app. // Log bucket for an extension.
message ExtensionInstallReport { message ExtensionInstallReport {
// Extension id for the extension. // Extension id for the extension.
optional string extension_id = 1; optional string extension_id = 1;
...@@ -2799,7 +2799,7 @@ message ExtensionInstallReport { ...@@ -2799,7 +2799,7 @@ message ExtensionInstallReport {
repeated ExtensionInstallReportLogEvent logs = 3; repeated ExtensionInstallReportLogEvent logs = 3;
} }
// Log bucket for an app. // Log bucket for an ARC++ app.
message AppInstallReport { message AppInstallReport {
// Package name of the app. // Package name of the app.
optional string package = 1; optional string package = 1;
...@@ -2812,12 +2812,18 @@ message AppInstallReport { ...@@ -2812,12 +2812,18 @@ message AppInstallReport {
repeated AppInstallReportLogEvent logs = 3; repeated AppInstallReportLogEvent logs = 3;
} }
// Push-install logs for all apps. // Push-install logs for all ARC++ apps.
message AppInstallReportRequest { message AppInstallReportRequest {
// Log buckets for each app. // Log buckets for each app.
repeated AppInstallReport app_install_reports = 1; repeated AppInstallReport app_install_reports = 1;
} }
// Installation logs for all extensions.
message ExtensionInstallReportRequest {
// Log buckets for each extension.
repeated ExtensionInstallReport extension_install_reports = 1;
}
// Response from server after receiving a report on the status of app // Response from server after receiving a report on the status of app
// push-installs. // push-installs.
message AppInstallReportResponse {} message AppInstallReportResponse {}
...@@ -3301,7 +3307,10 @@ message DeviceManagementRequest { ...@@ -3301,7 +3307,10 @@ message DeviceManagementRequest {
optional ClientCertificateProvisioningRequest optional ClientCertificateProvisioningRequest
client_certificate_provisioning_request = 34; client_certificate_provisioning_request = 34;
// Next id: 35. // A report on the status of extension install process.
optional ExtensionInstallReportRequest extension_install_report_request = 35;
// Next id: 36.
} }
// Response from server to device. // Response from server to device.
......
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