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

Refactor AppInstallEventLog and SingleAppInstallEventLog

AppInstallEventLog and SingleAppInstallEventLog classes are used for
storing logs on the disk and prepare for upload. Extract the common
code with ARC++ unspecific code into common classes. This is a
prework for adding similar classes for extension events.

Bug: 1081192
Change-Id: I481e864c89ce34fb9c8ddbd8983ad119be8bdf85
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2193675
Commit-Queue: Swapnil Gupta <swapnilgupta@google.com>
Reviewed-by: default avatarOleg Davydov <burunduk@chromium.org>
Reviewed-by: default avatarAskar Aitzhan <askaraitzhan@google.com>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775048}
parent d022c012
...@@ -1846,8 +1846,6 @@ source_set("chromeos") { ...@@ -1846,8 +1846,6 @@ source_set("chromeos") {
"policy/affiliated_invalidation_service_provider_impl.h", "policy/affiliated_invalidation_service_provider_impl.h",
"policy/android_management_client.cc", "policy/android_management_client.cc",
"policy/android_management_client.h", "policy/android_management_client.h",
"policy/app_install_event_log.cc",
"policy/app_install_event_log.h",
"policy/app_install_event_log_collector.cc", "policy/app_install_event_log_collector.cc",
"policy/app_install_event_log_collector.h", "policy/app_install_event_log_collector.h",
"policy/app_install_event_log_manager.cc", "policy/app_install_event_log_manager.cc",
...@@ -1860,6 +1858,8 @@ source_set("chromeos") { ...@@ -1860,6 +1858,8 @@ source_set("chromeos") {
"policy/app_install_event_log_util.h", "policy/app_install_event_log_util.h",
"policy/app_install_event_logger.cc", "policy/app_install_event_logger.cc",
"policy/app_install_event_logger.h", "policy/app_install_event_logger.h",
"policy/arc_app_install_event_log.cc",
"policy/arc_app_install_event_log.h",
"policy/auto_enrollment_client.h", "policy/auto_enrollment_client.h",
"policy/auto_enrollment_client_impl.cc", "policy/auto_enrollment_client_impl.cc",
"policy/auto_enrollment_client_impl.h", "policy/auto_enrollment_client_impl.h",
...@@ -1964,6 +1964,7 @@ source_set("chromeos") { ...@@ -1964,6 +1964,7 @@ source_set("chromeos") {
"policy/heartbeat_scheduler.h", "policy/heartbeat_scheduler.h",
"policy/hostname_handler.cc", "policy/hostname_handler.cc",
"policy/hostname_handler.h", "policy/hostname_handler.h",
"policy/install_event_log.h",
"policy/lock_to_single_user_manager.cc", "policy/lock_to_single_user_manager.cc",
"policy/lock_to_single_user_manager.h", "policy/lock_to_single_user_manager.h",
"policy/login_profile_policy_provider.cc", "policy/login_profile_policy_provider.cc",
...@@ -2042,8 +2043,9 @@ source_set("chromeos") { ...@@ -2042,8 +2043,9 @@ source_set("chromeos") {
"policy/server_backed_device_state.h", "policy/server_backed_device_state.h",
"policy/server_backed_state_keys_broker.cc", "policy/server_backed_state_keys_broker.cc",
"policy/server_backed_state_keys_broker.h", "policy/server_backed_state_keys_broker.h",
"policy/single_app_install_event_log.cc", "policy/single_arc_app_install_event_log.cc",
"policy/single_app_install_event_log.h", "policy/single_arc_app_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",
"policy/status_collector/affiliated_session_service.cc", "policy/status_collector/affiliated_session_service.cc",
...@@ -3121,9 +3123,9 @@ source_set("unit_tests") { ...@@ -3121,9 +3123,9 @@ source_set("unit_tests") {
"policy/app_install_event_log_collector_unittest.cc", "policy/app_install_event_log_collector_unittest.cc",
"policy/app_install_event_log_manager_unittest.cc", "policy/app_install_event_log_manager_unittest.cc",
"policy/app_install_event_log_manager_wrapper_unittest.cc", "policy/app_install_event_log_manager_wrapper_unittest.cc",
"policy/app_install_event_log_unittest.cc",
"policy/app_install_event_log_uploader_unittest.cc", "policy/app_install_event_log_uploader_unittest.cc",
"policy/app_install_event_logger_unittest.cc", "policy/app_install_event_logger_unittest.cc",
"policy/arc_app_install_event_log_unittest.cc",
"policy/auto_enrollment_client_impl_unittest.cc", "policy/auto_enrollment_client_impl_unittest.cc",
"policy/bluetooth_policy_handler_unittest.cc", "policy/bluetooth_policy_handler_unittest.cc",
"policy/cached_policy_key_loader_chromeos_unittest.cc", "policy/cached_policy_key_loader_chromeos_unittest.cc",
...@@ -3171,7 +3173,7 @@ source_set("unit_tests") { ...@@ -3171,7 +3173,7 @@ source_set("unit_tests") {
"policy/scheduled_update_checker/device_scheduled_update_checker_unittest.cc", "policy/scheduled_update_checker/device_scheduled_update_checker_unittest.cc",
"policy/secondary_google_account_signin_policy_handler_unittest.cc", "policy/secondary_google_account_signin_policy_handler_unittest.cc",
"policy/server_backed_state_keys_broker_unittest.cc", "policy/server_backed_state_keys_broker_unittest.cc",
"policy/single_app_install_event_log_unittest.cc", "policy/single_arc_app_install_event_log_unittest.cc",
"policy/status_collector/activity_storage_unittest.cc", "policy/status_collector/activity_storage_unittest.cc",
"policy/status_collector/affiliated_session_service_unittest.cc", "policy/status_collector/affiliated_session_service_unittest.cc",
"policy/status_collector/app_info_generator_unittest.cc", "policy/status_collector/app_info_generator_unittest.cc",
......
// Copyright 2018 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_APP_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_APP_INSTALL_EVENT_LOG_H_
#include <map>
#include <memory>
#include <string>
#include "base/files/file_path.h"
#include "base/macros.h"
namespace enterprise_management {
class AppInstallReportLogEvent;
class AppInstallReportRequest;
} // namespace enterprise_management
namespace policy {
class SingleAppInstallEventLog;
// An event log for app push-installs. The log entries for each app are kept in
// a separate round-robin buffer. The log can be stored on disk and serialized
// for upload to a server. Log entries are pruned after upload has completed.
class AppInstallEventLog {
public:
// Restores the event log from |file_name|. If there is an error parsing the
// file, as many log entries as possible are restored.
explicit AppInstallEventLog(const base::FilePath& file_name);
~AppInstallEventLog();
// The current total number of log entries, across all apps.
int total_size() { return total_size_; }
// The current maximum number of log entries for a single app.
int max_size() { return max_size_; }
// Add a log entry for |package|. If the buffer for that app is full, the
// oldest entry is removed.
void Add(const std::string& package,
const enterprise_management::AppInstallReportLogEvent& event);
// Stores the event log to the file name provided to the constructor. If the
// event log has not changed since it was last stored to disk (or initially
// loaded from disk), does nothing.
void Store();
// 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::AppInstallReportRequest* report);
// Clears log entries that were previously serialized.
void ClearSerialized();
private:
// The round-robin log event buffers for individual apps.
std::map<std::string, std::unique_ptr<SingleAppInstallEventLog>> logs_;
const base::FilePath file_name_;
// The current total number of log entries, across all apps.
int total_size_ = 0;
// The current maximum number of log entries for a single app.
int max_size_ = 0;
// Whether the event log changed since it was last stored to disk (or
// initially loaded from disk).
bool dirty_ = false;
DISALLOW_COPY_AND_ASSIGN(AppInstallEventLog);
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_APP_INSTALL_EVENT_LOG_H_
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/chromeos/policy/app_install_event_log.h"
#include "chrome/browser/chromeos/policy/app_install_event_log_uploader.h" #include "chrome/browser/chromeos/policy/app_install_event_log_uploader.h"
#include "chrome/browser/chromeos/policy/arc_app_install_event_log.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
...@@ -167,7 +167,7 @@ AppInstallEventLogManager::LogSize AppInstallEventLogManager::Log::Init( ...@@ -167,7 +167,7 @@ AppInstallEventLogManager::LogSize AppInstallEventLogManager::Log::Init(
const base::FilePath& file_path) { const base::FilePath& file_path) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!log_); DCHECK(!log_);
log_ = std::make_unique<AppInstallEventLog>(file_path); log_ = std::make_unique<ArcAppInstallEventLog>(file_path);
return GetSize(); return GetSize();
} }
......
...@@ -30,12 +30,12 @@ class AppInstallReportRequest; ...@@ -30,12 +30,12 @@ class AppInstallReportRequest;
namespace policy { namespace policy {
class AppInstallEventLog; class ArcAppInstallEventLog;
// Ties together collection, storage and upload of app push-install event logs. // Ties together collection, storage and upload of app push-install event logs.
// Owns an |AppInstallEventLog| for log storage and an |AppInstallEventLogger| // Owns an |ArcAppInstallEventLog| for log storage and an
// for log collection. The |AppInstallEventUploader| is passed to the // |AppInstallEventLogger| for log collection. The |AppInstallEventUploader| is
// constructor and must outlive |this|. // passed to the constructor and must outlive |this|.
// //
// Newly added log entries are held in memory first and stored to disk no more // Newly added log entries are held in memory first and stored to disk no more
// than five seconds later. The log is also written to disk every time it has // than five seconds later. The log is also written to disk every time it has
...@@ -148,7 +148,7 @@ class AppInstallEventLogManager : public AppInstallEventLogger::Delegate, ...@@ -148,7 +148,7 @@ class AppInstallEventLogManager : public AppInstallEventLogger::Delegate,
LogSize GetSize() const; LogSize GetSize() const;
// The actual log store. // The actual log store.
std::unique_ptr<AppInstallEventLog> log_; std::unique_ptr<ArcAppInstallEventLog> log_;
// Ensures that methods are not called from the wrong thread. // Ensures that methods are not called from the wrong thread.
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#include "base/time/tick_clock.h" #include "base/time/tick_clock.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/chromeos/policy/app_install_event_log.h"
#include "chrome/browser/chromeos/policy/app_install_event_log_uploader.h" #include "chrome/browser/chromeos/policy/app_install_event_log_uploader.h"
#include "chrome/browser/chromeos/policy/app_install_event_log_util.h" #include "chrome/browser/chromeos/policy/app_install_event_log_util.h"
#include "chrome/browser/chromeos/policy/arc_app_install_event_log.h"
#include "chrome/browser/profiles/reporting_util.h" #include "chrome/browser/profiles/reporting_util.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "chromeos/system/fake_statistics_provider.h" #include "chromeos/system/fake_statistics_provider.h"
...@@ -285,7 +285,7 @@ class AppInstallEventLogManagerTest : public testing::Test { ...@@ -285,7 +285,7 @@ class AppInstallEventLogManagerTest : public testing::Test {
void VerifyLogFile() { void VerifyLogFile() {
EXPECT_TRUE(base::PathExists(log_file_path_)); EXPECT_TRUE(base::PathExists(log_file_path_));
AppInstallEventLog log(log_file_path_); ArcAppInstallEventLog log(log_file_path_);
em::AppInstallReportRequest log_events; em::AppInstallReportRequest log_events;
log.Serialize(&log_events); log.Serialize(&log_events);
EXPECT_TRUE(ContainsSameEvents(events_, log_events)); EXPECT_TRUE(ContainsSameEvents(events_, log_events));
...@@ -337,7 +337,7 @@ TEST_F(AppInstallEventLogManagerTest, CreateEmpty) { ...@@ -337,7 +337,7 @@ TEST_F(AppInstallEventLogManagerTest, CreateEmpty) {
// the log. Verify that no store is scheduled and an expedited initial upload // the log. Verify that no store is scheduled and an expedited initial upload
// occurs after fifteen minutes. // occurs after fifteen minutes.
TEST_F(AppInstallEventLogManagerTest, CreateNonEmpty) { TEST_F(AppInstallEventLogManagerTest, CreateNonEmpty) {
AppInstallEventLog log(log_file_path_); ArcAppInstallEventLog log(log_file_path_);
events_[kPackageNames[0]].push_back(event_); events_[kPackageNames[0]].push_back(event_);
log.Add(kPackageNames[0], event_); log.Add(kPackageNames[0], event_);
log.Store(); log.Store();
...@@ -734,7 +734,7 @@ TEST_F(AppInstallEventLogManagerTest, StoreOnShutdown) { ...@@ -734,7 +734,7 @@ TEST_F(AppInstallEventLogManagerTest, StoreOnShutdown) {
// to the app-install event log. Verify that the prefs are cleared and an // to the app-install event log. Verify that the prefs are cleared and an
// immediate deletion of the log file is scheduled. // immediate deletion of the log file is scheduled.
TEST_F(AppInstallEventLogManagerTest, Clear) { TEST_F(AppInstallEventLogManagerTest, Clear) {
AppInstallEventLog log(log_file_path_); ArcAppInstallEventLog log(log_file_path_);
events_[kPackageNames[0]].push_back(event_); events_[kPackageNames[0]].push_back(event_);
log.Add(kPackageNames[0], event_); log.Add(kPackageNames[0], event_);
log.Store(); log.Store();
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "chrome/browser/chromeos/policy/app_install_event_log.h" #include "chrome/browser/chromeos/policy/arc_app_install_event_log.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "components/arc/arc_prefs.h" #include "components/arc/arc_prefs.h"
...@@ -67,7 +67,7 @@ class AppInstallEventLogManagerWrapperTest : public testing::Test { ...@@ -67,7 +67,7 @@ class AppInstallEventLogManagerWrapperTest : public testing::Test {
void SetUp() override { app_list_.AppendString(kPackageName); } void SetUp() override { app_list_.AppendString(kPackageName); }
void PopulateLogFileAndPrefs() { void PopulateLogFileAndPrefs() {
AppInstallEventLog log(log_file_path_); ArcAppInstallEventLog log(log_file_path_);
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_timestamp(0); event.set_timestamp(0);
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
......
// Copyright 2018 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/arc_app_install_event_log.h"
#include "components/policy/proto/device_management_backend.pb.h"
namespace em = enterprise_management;
namespace policy {
ArcAppInstallEventLog::ArcAppInstallEventLog(const base::FilePath& file_name)
: InstallEventLog(file_name) {}
ArcAppInstallEventLog::~ArcAppInstallEventLog() = default;
void ArcAppInstallEventLog::Serialize(em::AppInstallReportRequest* report) {
report->Clear();
for (const auto& log : logs_) {
em::AppInstallReport* const report_log = report->add_app_install_reports();
log.second->Serialize(report_log);
}
}
} // namespace policy
// Copyright 2018 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_ARC_APP_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_ARC_APP_INSTALL_EVENT_LOG_H_
#include "chrome/browser/chromeos/policy/install_event_log.h"
#include "chrome/browser/chromeos/policy/single_arc_app_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 ARC++ app push-installs.
class ArcAppInstallEventLog
: public InstallEventLog<enterprise_management::AppInstallReportLogEvent,
SingleArcAppInstallEventLog> {
public:
explicit ArcAppInstallEventLog(const base::FilePath& file_name);
~ArcAppInstallEventLog();
// 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::AppInstallReportRequest* report);
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_ARC_APP_INSTALL_EVENT_LOG_H_
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/chromeos/policy/app_install_event_log.h" #ifndef CHROME_BROWSER_CHROMEOS_POLICY_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_INSTALL_EVENT_LOG_H_
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <algorithm> #include <algorithm>
#include <map>
#include <memory> #include <memory>
#include <string>
#include <utility> #include <utility>
#include "base/files/file.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/chromeos/policy/single_app_install_event_log.h" #include "base/macros.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "chrome/browser/chromeos/policy/single_install_event_log.h"
namespace em = enterprise_management;
namespace policy { namespace policy {
namespace { // An event log for app installs. The app refers to extension or ARC++ app. The
constexpr int64_t kLogFileVersion = 3; // log entries for each app are kept in a separate round-robin buffer. The log
constexpr ssize_t kMaxLogs = 1024; // can be stored on disk and serialized for upload to a server. Log entries are
} // namespace // pruned after upload has completed. Uses a sequence checker in
// |AppInstallEventLogManager| to ensure that methods are called from the
// right thread. |T| specifies the event type, and |C| specifies the event log
// class for single app.
template <typename T, typename C>
class InstallEventLog {
public:
// Restores the event log from |file_name|. If there is an error parsing the
// file, as many log entries as possible are restored.
explicit InstallEventLog(const base::FilePath& file_name);
~InstallEventLog();
// The current total number of log entries across apps.
int total_size() { return total_size_; }
// The current maximum number of log entries for a single app.
int max_size() { return max_size_; }
// Add a log entry for |id|. If the buffer for that app is
// full, the oldest entry is removed.
void Add(const std::string& id, const T& event);
// Stores the event log to the file name provided to the constructor. If the
// event log has not changed since it was last stored to disk (or initially
// loaded from disk), does nothing.
void Store();
// Clears log entries that were previously serialized.
void ClearSerialized();
static constexpr int64_t kLogFileVersion = 3;
static constexpr ssize_t kMaxLogs = 1024;
protected:
// The round-robin log event buffers for individual apps.
std::map<std::string, std::unique_ptr<C>> logs_;
const base::FilePath file_name_;
// The current total number of log entries, across all apps.
int total_size_ = 0;
AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name) // The current maximum number of log entries for a single app.
int max_size_ = 0;
// Whether the event log changed since it was last stored to disk (or
// initially loaded from disk).
bool dirty_ = false;
};
// Implementation details below here.
template <typename T, typename C>
constexpr int64_t InstallEventLog<T, C>::kLogFileVersion;
template <typename T, typename C>
constexpr ssize_t InstallEventLog<T, C>::kMaxLogs;
template <typename T, typename C>
InstallEventLog<T, C>::InstallEventLog(const base::FilePath& file_name)
: file_name_(file_name) { : file_name_(file_name) {
base::File file(file_name_, base::File::FLAG_OPEN | base::File::FLAG_READ); base::File file(file_name_, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) if (!file.IsValid())
...@@ -34,7 +91,7 @@ AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name) ...@@ -34,7 +91,7 @@ AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name)
int64_t version; int64_t version;
if (!file.ReadAtCurrentPosAndCheck( if (!file.ReadAtCurrentPosAndCheck(
base::as_writable_bytes(base::make_span(&version, 1)))) { base::as_writable_bytes(base::make_span(&version, 1)))) {
LOG(WARNING) << "Corrupted app install log."; LOG(WARNING) << "Corrupted install log.";
return; return;
} }
...@@ -46,22 +103,22 @@ AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name) ...@@ -46,22 +103,22 @@ AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name)
ssize_t entries; ssize_t entries;
if (!file.ReadAtCurrentPosAndCheck( if (!file.ReadAtCurrentPosAndCheck(
base::as_writable_bytes(base::make_span(&entries, 1)))) { base::as_writable_bytes(base::make_span(&entries, 1)))) {
LOG(WARNING) << "Corrupted app install log."; LOG(WARNING) << "Corrupted install log.";
return; return;
} }
for (int i = 0; i < std::min(entries, kMaxLogs); ++i) { for (int i = 0; i < std::min(entries, kMaxLogs); ++i) {
std::unique_ptr<SingleAppInstallEventLog> log; std::unique_ptr<C> log;
const bool file_ok = SingleAppInstallEventLog::Load(&file, &log); const bool file_ok = C::Load(&file, &log);
const bool log_ok = log && !log->package().empty() && const bool log_ok =
logs_.find(log->package()) == logs_.end(); log && !log->id().empty() && logs_.find(log->id()) == logs_.end();
if (!file_ok || !log_ok) { if (!file_ok || !log_ok) {
LOG(WARNING) << "Corrupted app install log."; LOG(WARNING) << "Corrupted install log.";
} }
if (log_ok) { if (log_ok) {
total_size_ += log->size(); total_size_ += log->size();
max_size_ = std::max(max_size_, log->size()); max_size_ = std::max(max_size_, log->size());
logs_[log->package()] = std::move(log); logs_[log->id()] = std::move(log);
} }
if (!file_ok) { if (!file_ok) {
return; return;
...@@ -69,22 +126,24 @@ AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name) ...@@ -69,22 +126,24 @@ AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name)
} }
if (entries >= kMaxLogs) { if (entries >= kMaxLogs) {
LOG(WARNING) << "Corrupted app install log."; LOG(WARNING) << "Corrupted install log.";
} }
} }
AppInstallEventLog::~AppInstallEventLog() = default; template <typename T, typename C>
InstallEventLog<T, C>::~InstallEventLog() = default;
void AppInstallEventLog::Add(const std::string& package, template <typename T, typename C>
const em::AppInstallReportLogEvent& event) { void InstallEventLog<T, C>::Add(const std::string& extension_id,
if (logs_.size() == kMaxLogs && logs_.find(package) == logs_.end()) { const T& event) {
LOG(WARNING) << "App install log overflow."; if (logs_.size() == kMaxLogs && logs_.find(extension_id) == logs_.end()) {
LOG(WARNING) << "Install log overflow.";
return; return;
} }
auto& log = logs_[package]; auto& log = logs_[extension_id];
if (!log) if (!log)
log = std::make_unique<SingleAppInstallEventLog>(package); log = std::make_unique<C>(extension_id);
total_size_ -= log->size(); total_size_ -= log->size();
log->Add(event); log->Add(event);
total_size_ += log->size(); total_size_ += log->size();
...@@ -92,7 +151,8 @@ void AppInstallEventLog::Add(const std::string& package, ...@@ -92,7 +151,8 @@ void AppInstallEventLog::Add(const std::string& package,
dirty_ = true; dirty_ = true;
} }
void AppInstallEventLog::Store() { template <typename T, typename C>
void InstallEventLog<T, C>::Store() {
if (!dirty_) { if (!dirty_) {
return; return;
} }
...@@ -100,26 +160,26 @@ void AppInstallEventLog::Store() { ...@@ -100,26 +160,26 @@ void AppInstallEventLog::Store() {
base::File file(file_name_, base::File file(file_name_,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
if (!file.IsValid()) { if (!file.IsValid()) {
LOG(WARNING) << "Unable to store app install log."; LOG(WARNING) << "Unable to store install log.";
return; return;
} }
if (!file.WriteAtCurrentPosAndCheck( if (!file.WriteAtCurrentPosAndCheck(
base::as_bytes(base::make_span(&kLogFileVersion, 1)))) { base::as_bytes(base::make_span(&kLogFileVersion, 1)))) {
LOG(WARNING) << "Unable to store app install log."; LOG(WARNING) << "Unable to store install log.";
return; return;
} }
ssize_t entries = logs_.size(); ssize_t entries = logs_.size();
if (!file.WriteAtCurrentPosAndCheck( if (!file.WriteAtCurrentPosAndCheck(
base::as_bytes(base::make_span(&entries, 1)))) { base::as_bytes(base::make_span(&entries, 1)))) {
LOG(WARNING) << "Unable to store app install log."; LOG(WARNING) << "Unable to store install log.";
return; return;
} }
for (const auto& log : logs_) { for (const auto& log : logs_) {
if (!log.second->Store(&file)) { if (!log.second->Store(&file)) {
LOG(WARNING) << "Unable to store app install log."; LOG(WARNING) << "Unable to store install log.";
return; return;
} }
} }
...@@ -127,15 +187,8 @@ void AppInstallEventLog::Store() { ...@@ -127,15 +187,8 @@ void AppInstallEventLog::Store() {
dirty_ = false; dirty_ = false;
} }
void AppInstallEventLog::Serialize(em::AppInstallReportRequest* report) { template <typename T, typename C>
report->Clear(); void InstallEventLog<T, C>::ClearSerialized() {
for (const auto& log : logs_) {
em::AppInstallReport* const report_log = report->add_app_install_reports();
log.second->Serialize(report_log);
}
}
void AppInstallEventLog::ClearSerialized() {
int total_size = 0; int total_size = 0;
max_size_ = 0; max_size_ = 0;
...@@ -158,3 +211,5 @@ void AppInstallEventLog::ClearSerialized() { ...@@ -158,3 +211,5 @@ void AppInstallEventLog::ClearSerialized() {
} }
} // namespace policy } // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_INSTALL_EVENT_LOG_H_
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/chromeos/policy/single_app_install_event_log.h" #include "chrome/browser/chromeos/policy/single_arc_app_install_event_log.h"
#include <stddef.h>
#include <stdint.h>
#include "base/files/file.h" #include "base/files/file.h"
...@@ -13,30 +10,15 @@ namespace em = enterprise_management; ...@@ -13,30 +10,15 @@ namespace em = enterprise_management;
namespace policy { namespace policy {
namespace { SingleArcAppInstallEventLog::SingleArcAppInstallEventLog(
static const int kLogCapacity = 1024; const std::string& package)
static const int kMaxBufferSize = 65536; : SingleInstallEventLog(package) {}
} // namespace
SingleAppInstallEventLog::SingleAppInstallEventLog(const std::string& package)
: package_(package) {}
SingleAppInstallEventLog::~SingleAppInstallEventLog() {}
void SingleAppInstallEventLog::Add(const em::AppInstallReportLogEvent& event) { SingleArcAppInstallEventLog::~SingleArcAppInstallEventLog() {}
events_.push_back(event);
if (events_.size() > kLogCapacity) {
incomplete_ = true;
if (serialized_entries_ > -1) {
--serialized_entries_;
}
events_.pop_front();
}
}
bool SingleAppInstallEventLog::Load( bool SingleArcAppInstallEventLog::Load(
base::File* file, base::File* file,
std::unique_ptr<SingleAppInstallEventLog>* log) { std::unique_ptr<SingleArcAppInstallEventLog>* log) {
log->reset(); log->reset();
if (!file->IsValid()) { if (!file->IsValid()) {
...@@ -55,7 +37,7 @@ bool SingleAppInstallEventLog::Load( ...@@ -55,7 +37,7 @@ bool SingleAppInstallEventLog::Load(
return false; return false;
} }
*log = std::make_unique<SingleAppInstallEventLog>( *log = std::make_unique<SingleArcAppInstallEventLog>(
std::string(package_buffer.get(), size)); std::string(package_buffer.get(), size));
int64_t incomplete; int64_t incomplete;
...@@ -103,61 +85,9 @@ bool SingleAppInstallEventLog::Load( ...@@ -103,61 +85,9 @@ bool SingleAppInstallEventLog::Load(
return true; return true;
} }
bool SingleAppInstallEventLog::Store(base::File* file) const { void SingleArcAppInstallEventLog::Serialize(em::AppInstallReport* report) {
if (!file->IsValid()) {
return false;
}
ssize_t size = package_.size();
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&size),
sizeof(size)) != sizeof(size)) {
return false;
}
if (file->WriteAtCurrentPos(package_.data(), size) != size) {
return false;
}
const int64_t incomplete = incomplete_;
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&incomplete),
sizeof(incomplete)) != sizeof(incomplete)) {
return false;
}
const ssize_t entries = events_.size();
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&entries),
sizeof(entries)) != sizeof(entries)) {
return false;
}
for (const em::AppInstallReportLogEvent& event : events_) {
size = event.ByteSizeLong();
std::unique_ptr<char[]> buffer;
if (size > kMaxBufferSize) {
// Log entry too large. Skip it.
size = 0;
} else {
buffer = std::make_unique<char[]>(size);
if (!event.SerializeToArray(buffer.get(), size)) {
// Log entry serialization failed. Skip it.
size = 0;
}
}
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&size),
sizeof(size)) != sizeof(size) ||
(size && file->WriteAtCurrentPos(buffer.get(), size) != size)) {
return false;
}
}
return true;
}
void SingleAppInstallEventLog::Serialize(em::AppInstallReport* report) {
report->Clear(); report->Clear();
report->set_package(package_); report->set_package(id_);
report->set_incomplete(incomplete_); report->set_incomplete(incomplete_);
for (const auto& event : events_) { for (const auto& event : events_) {
em::AppInstallReportLogEvent* const log_event = report->add_logs(); em::AppInstallReportLogEvent* const log_event = report->add_logs();
...@@ -166,14 +96,4 @@ void SingleAppInstallEventLog::Serialize(em::AppInstallReport* report) { ...@@ -166,14 +96,4 @@ void SingleAppInstallEventLog::Serialize(em::AppInstallReport* report) {
serialized_entries_ = events_.size(); serialized_entries_ = events_.size();
} }
void SingleAppInstallEventLog::ClearSerialized() {
if (serialized_entries_ == -1) {
return;
}
events_.erase(events_.begin(), events_.begin() + serialized_entries_);
serialized_entries_ = -1;
incomplete_ = false;
}
} // namespace policy } // namespace policy
...@@ -2,42 +2,27 @@ ...@@ -2,42 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_APP_INSTALL_EVENT_LOG_H_ #ifndef CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_ARC_APP_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_APP_INSTALL_EVENT_LOG_H_ #define CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_ARC_APP_INSTALL_EVENT_LOG_H_
#include <deque>
#include <memory>
#include <string> #include <string>
#include "chrome/browser/chromeos/policy/single_install_event_log.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "base/macros.h"
namespace base { namespace base {
class File; class File;
} }
namespace policy { namespace policy {
// An event log for a single app's push-install process. The log can be stored // An event log for a single ARC++ app's push-install process.
// on disk and serialized for upload to a server. The log is internally held in class SingleArcAppInstallEventLog
// a round-robin buffer. A flag indicates whether any log entries were lost : public SingleInstallEventLog<
// (e.g. entry too large or buffer wrapped around). Log entries are pruned and enterprise_management::AppInstallReportLogEvent> {
// the flag is cleared after upload has completed.
class SingleAppInstallEventLog {
public: public:
explicit SingleAppInstallEventLog(const std::string& package); explicit SingleArcAppInstallEventLog(const std::string& package);
~SingleAppInstallEventLog(); ~SingleArcAppInstallEventLog();
const std::string& package() const { return package_; }
int size() const { return events_.size(); }
bool empty() const { return events_.empty(); }
// Add a log entry. If the buffer is full, the oldest entry is removed and
// |incomplete_| is set.
void Add(const enterprise_management::AppInstallReportLogEvent& event);
// 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
...@@ -46,41 +31,14 @@ class SingleAppInstallEventLog { ...@@ -46,41 +31,14 @@ class SingleAppInstallEventLog {
// file, the buffer wraps around or any log entries cannot be fully parsed. If // file, the buffer wraps around or any log entries cannot be fully parsed. If
// not even the app name can be parsed, |log| is set to |nullptr|. // 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<SingleAppInstallEventLog>* log); std::unique_ptr<SingleArcAppInstallEventLog>* log);
// Stores the event log to |file|. Returns |true| if the log was written
// successfully in a self-delimiting manner and the file may be used to store
// further logs.
bool Store(base::File* file) const;
// Serializes the log to a protobuf for upload to a server. Records which // Serializes the log to a protobuf for upload to a server. Records which
// entries were serialized so that they may be cleared after successful // entries were serialized so that they may be cleared after successful
// upload. // upload.
void Serialize(enterprise_management::AppInstallReport* report); void Serialize(enterprise_management::AppInstallReport* report);
// Clears log entries that were previously serialized. Also clears
// |incomplete_| if all log entries added since serialization are still
// present in the log.
void ClearSerialized();
private:
// The app this event log pertains to.
const std::string package_;
// The buffer holding log entries.
std::deque<enterprise_management::AppInstallReportLogEvent> events_;
// Whether any log entries were lost (e.g. entry too large or buffer wrapped
// around).
bool incomplete_ = false;
// The number of entries that were serialized and can be cleared from the log
// after successful upload to the server, or -1 if none.
int serialized_entries_ = -1;
DISALLOW_COPY_AND_ASSIGN(SingleAppInstallEventLog);
}; };
} // namespace policy } // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_APP_INSTALL_EVENT_LOG_H_ #endif // CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_ARC_APP_INSTALL_EVENT_LOG_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.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_INSTALL_EVENT_LOG_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_INSTALL_EVENT_LOG_H_
#include <stddef.h>
#include <stdint.h>
#include <deque>
#include <memory>
#include <string>
#include "base/files/file.h"
namespace policy {
// An event log for install process of single app. App refers to extension or
// ARC++ app. The log can be stored on disk and serialized for upload to a
// server. The log is internally held in a round-robin buffer. An |incomplete_|
// flag indicates whether any log entries were lost (e.g. entry too large or
// buffer wrapped around). Log entries are pruned and the flag is cleared after
// upload has completed. |T| specifies the event type.
template <typename T>
class SingleInstallEventLog {
public:
explicit SingleInstallEventLog(const std::string& id);
~SingleInstallEventLog();
const std::string& id() const { return id_; }
int size() const { return events_.size(); }
bool empty() const { return events_.empty(); }
// Add a log entry. If the buffer is full, the oldest entry is removed and
// |incomplete_| is set.
void Add(const T& event);
// Stores the event log to |file|. Returns |true| if the log was written
// successfully in a self-delimiting manner and the file may be used to store
// further logs.
bool Store(base::File* file) const;
// Clears log entries that were previously serialized. Also clears
// |incomplete_| if all log entries added since serialization are still
// present in the log.
void ClearSerialized();
static const int kLogCapacity = 1024;
static const int kMaxBufferSize = 65536;
protected:
// The app this event log pertains to.
const std::string id_;
// The buffer holding log entries.
std::deque<T> events_;
// Whether any log entries were lost (e.g. entry too large or buffer wrapped
// around).
bool incomplete_ = false;
// The number of entries that were serialized and can be cleared from the log
// after successful upload to the server, or -1 if none.
int serialized_entries_ = -1;
};
// Implementation details below here.
template <typename T>
const int SingleInstallEventLog<T>::kLogCapacity;
template <typename T>
const int SingleInstallEventLog<T>::kMaxBufferSize;
template <typename T>
SingleInstallEventLog<T>::SingleInstallEventLog(const std::string& id)
: id_(id) {}
template <typename T>
SingleInstallEventLog<T>::~SingleInstallEventLog() {}
template <typename T>
void SingleInstallEventLog<T>::Add(const T& event) {
events_.push_back(event);
if (events_.size() > kLogCapacity) {
incomplete_ = true;
if (serialized_entries_ > -1) {
--serialized_entries_;
}
events_.pop_front();
}
}
template <typename T>
bool SingleInstallEventLog<T>::Store(base::File* file) const {
if (!file->IsValid()) {
return false;
}
ssize_t size = id_.size();
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&size),
sizeof(size)) != sizeof(size)) {
return false;
}
if (file->WriteAtCurrentPos(id_.data(), size) != size) {
return false;
}
const int64_t incomplete = incomplete_;
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&incomplete),
sizeof(incomplete)) != sizeof(incomplete)) {
return false;
}
const ssize_t entries = events_.size();
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&entries),
sizeof(entries)) != sizeof(entries)) {
return false;
}
for (const T& event : events_) {
size = event.ByteSizeLong();
std::unique_ptr<char[]> buffer;
if (size > kMaxBufferSize) {
// Log entry too large. Skip it.
size = 0;
} else {
buffer = std::make_unique<char[]>(size);
if (!event.SerializeToArray(buffer.get(), size)) {
// Log entry serialization failed. Skip it.
size = 0;
}
}
if (file->WriteAtCurrentPos(reinterpret_cast<const char*>(&size),
sizeof(size)) != sizeof(size) ||
(size && file->WriteAtCurrentPos(buffer.get(), size) != size)) {
return false;
}
}
return true;
}
template <typename T>
void SingleInstallEventLog<T>::ClearSerialized() {
if (serialized_entries_ == -1) {
return;
}
events_.erase(events_.begin(), events_.begin() + serialized_entries_);
serialized_entries_ = -1;
incomplete_ = false;
}
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_SINGLE_INSTALL_EVENT_LOG_H_
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