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_
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// 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" #include "chrome/browser/chromeos/policy/arc_app_install_event_log.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/files/file.h" #include "base/files/file.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "chrome/browser/chromeos/policy/single_arc_app_install_event_log.h"
#include "components/policy/proto/device_management_backend.pb.h" #include "components/policy/proto/device_management_backend.pb.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -22,9 +23,6 @@ namespace policy { ...@@ -22,9 +23,6 @@ namespace policy {
namespace { namespace {
static const int kLogCapacity = 1024;
static const int kMaxLogs = 1024;
static const char kFirstPackageName[] = "com.example.first"; static const char kFirstPackageName[] = "com.example.first";
static const char kSecondPackageName[] = "com.example.second"; static const char kSecondPackageName[] = "com.example.second";
static const char kPackageNameTemplate[] = "com.example."; static const char kPackageNameTemplate[] = "com.example.";
...@@ -32,14 +30,14 @@ static const char kFileName[] = "event.log"; ...@@ -32,14 +30,14 @@ static const char kFileName[] = "event.log";
} // namespace } // namespace
class AppInstallEventLogTest : public testing::Test { class ArcAppInstallEventLogTest : public testing::Test {
protected: protected:
AppInstallEventLogTest() {} ArcAppInstallEventLogTest() {}
void SetUp() override { void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
file_name_ = temp_dir_.GetPath().Append(kFileName); file_name_ = temp_dir_.GetPath().Append(kFileName);
log_ = std::make_unique<AppInstallEventLog>(file_name_); log_ = std::make_unique<ArcAppInstallEventLog>(file_name_);
} }
void VerifyTenLogEntriesEach(int first_app_timestamp_offset, void VerifyTenLogEntriesEach(int first_app_timestamp_offset,
...@@ -71,31 +69,32 @@ class AppInstallEventLogTest : public testing::Test { ...@@ -71,31 +69,32 @@ class AppInstallEventLogTest : public testing::Test {
void OverflowMaxLogs() { void OverflowMaxLogs() {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < kMaxLogs - 1; ++i) { for (int i = 0; i < ArcAppInstallEventLog::kMaxLogs - 1; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
std::stringstream package; std::stringstream package;
package << kPackageNameTemplate << i; package << kPackageNameTemplate << i;
log_->Add(package.str(), event); log_->Add(package.str(), event);
} }
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
event.set_timestamp(i + kMaxLogs - 1); event.set_timestamp(i + ArcAppInstallEventLog::kMaxLogs - 1);
log_->Add(kFirstPackageName, event); log_->Add(kFirstPackageName, event);
} }
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
event.set_timestamp(i + kMaxLogs + 29); event.set_timestamp(i + ArcAppInstallEventLog::kMaxLogs + 29);
log_->Add(kSecondPackageName, event); log_->Add(kSecondPackageName, event);
} }
} }
void VerifyOneLogEntryEachPlusFirstApp(int first_app_log_entries) { void VerifyOneLogEntryEachPlusFirstApp(int first_app_log_entries) {
ASSERT_EQ(kMaxLogs, report_.app_install_reports_size()); ASSERT_EQ(ArcAppInstallEventLog::kMaxLogs,
report_.app_install_reports_size());
std::map<std::string, em::AppInstallReport> logs; std::map<std::string, em::AppInstallReport> logs;
for (int i = 0; i < kMaxLogs; ++i) { for (int i = 0; i < ArcAppInstallEventLog::kMaxLogs; ++i) {
logs[report_.app_install_reports(i).package()] = logs[report_.app_install_reports(i).package()] =
report_.app_install_reports(i); report_.app_install_reports(i);
} }
for (int i = 0; i < kMaxLogs - 1; ++i) { for (int i = 0; i < ArcAppInstallEventLog::kMaxLogs - 1; ++i) {
std::stringstream package; std::stringstream package;
package << kPackageNameTemplate << i; package << kPackageNameTemplate << i;
const auto log = logs.find(package.str()); const auto log = logs.find(package.str());
...@@ -112,7 +111,8 @@ class AppInstallEventLogTest : public testing::Test { ...@@ -112,7 +111,8 @@ class AppInstallEventLogTest : public testing::Test {
EXPECT_EQ(kFirstPackageName, log->second.package()); EXPECT_EQ(kFirstPackageName, log->second.package());
ASSERT_EQ(first_app_log_entries, log->second.logs_size()); ASSERT_EQ(first_app_log_entries, log->second.logs_size());
for (int i = 0; i < first_app_log_entries; ++i) { for (int i = 0; i < first_app_log_entries; ++i) {
EXPECT_EQ(i + kMaxLogs - 1, log->second.logs(i).timestamp()); EXPECT_EQ(i + ArcAppInstallEventLog::kMaxLogs - 1,
log->second.logs(i).timestamp());
EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS, EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS,
log->second.logs(i).event_type()); log->second.logs(i).event_type());
} }
...@@ -122,16 +122,16 @@ class AppInstallEventLogTest : public testing::Test { ...@@ -122,16 +122,16 @@ class AppInstallEventLogTest : public testing::Test {
base::ScopedTempDir temp_dir_; base::ScopedTempDir temp_dir_;
base::FilePath file_name_; base::FilePath file_name_;
std::unique_ptr<AppInstallEventLog> log_; std::unique_ptr<ArcAppInstallEventLog> log_;
em::AppInstallReportRequest report_; em::AppInstallReportRequest report_;
private: private:
DISALLOW_COPY_AND_ASSIGN(AppInstallEventLogTest); DISALLOW_COPY_AND_ASSIGN(ArcAppInstallEventLogTest);
}; };
// Do not add any log entries. Serialize the log. Verify that the serialization // Do not add any log entries. Serialize the log. Verify that the serialization
// contains no log entries. // contains no log entries.
TEST_F(AppInstallEventLogTest, SerializeEmpty) { TEST_F(ArcAppInstallEventLogTest, SerializeEmpty) {
EXPECT_EQ(0, log_->total_size()); EXPECT_EQ(0, log_->total_size());
EXPECT_EQ(0, log_->max_size()); EXPECT_EQ(0, log_->max_size());
...@@ -141,7 +141,7 @@ TEST_F(AppInstallEventLogTest, SerializeEmpty) { ...@@ -141,7 +141,7 @@ TEST_F(AppInstallEventLogTest, SerializeEmpty) {
// Populate the logs for two apps. Verify that the entries are serialized // Populate the logs for two apps. Verify that the entries are serialized
// correctly. // correctly.
TEST_F(AppInstallEventLogTest, AddAndSerialize) { TEST_F(ArcAppInstallEventLogTest, AddAndSerialize) {
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);
...@@ -182,7 +182,7 @@ TEST_F(AppInstallEventLogTest, AddAndSerialize) { ...@@ -182,7 +182,7 @@ TEST_F(AppInstallEventLogTest, AddAndSerialize) {
// Add 10 log entries for an app. Serialize the log. Clear the serialized log // Add 10 log entries for an app. Serialize the log. Clear the serialized log
// entries and verify that the log becomes empty. Then, serialize the log again // entries and verify that the log becomes empty. Then, serialize the log again
// and verify it contains no log entries. // and verify it contains no log entries.
TEST_F(AppInstallEventLogTest, SerializeAndClear) { TEST_F(ArcAppInstallEventLogTest, SerializeAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -207,7 +207,7 @@ TEST_F(AppInstallEventLogTest, SerializeAndClear) { ...@@ -207,7 +207,7 @@ TEST_F(AppInstallEventLogTest, SerializeAndClear) {
// entries each for the first and a second app. Clear the serialized log // entries each for the first and a second app. Clear the serialized log
// entries. Then, serialize the log again. Verify that it now contains the // entries. Then, serialize the log again. Verify that it now contains the
// entries added after the first serialization. // entries added after the first serialization.
TEST_F(AppInstallEventLogTest, SerializeAddClearAndSerialize) { TEST_F(ArcAppInstallEventLogTest, SerializeAddClearAndSerialize) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -243,9 +243,9 @@ TEST_F(AppInstallEventLogTest, SerializeAddClearAndSerialize) { ...@@ -243,9 +243,9 @@ TEST_F(AppInstallEventLogTest, SerializeAddClearAndSerialize) {
// more app. Serialize the log. Verify that the log entries for the last app // more app. Serialize the log. Verify that the log entries for the last app
// were ignored. Then, clear the serialized log entries. Verify that the log // were ignored. Then, clear the serialized log entries. Verify that the log
// becomes empty. // becomes empty.
TEST_F(AppInstallEventLogTest, OverflowSerializeAndClear) { TEST_F(ArcAppInstallEventLogTest, OverflowSerializeAndClear) {
OverflowMaxLogs(); OverflowMaxLogs();
EXPECT_EQ(kMaxLogs + 9, log_->total_size()); EXPECT_EQ(ArcAppInstallEventLog::kMaxLogs + 9, log_->total_size());
EXPECT_EQ(10, log_->max_size()); EXPECT_EQ(10, log_->max_size());
log_->Serialize(&report_); log_->Serialize(&report_);
...@@ -264,15 +264,15 @@ TEST_F(AppInstallEventLogTest, OverflowSerializeAndClear) { ...@@ -264,15 +264,15 @@ TEST_F(AppInstallEventLogTest, OverflowSerializeAndClear) {
// more app. Add more entries for one of the apps already in the log. Serialize // more app. Add more entries for one of the apps already in the log. Serialize
// the log. Verify that the log entries for the last app were ignored. Then, // the log. Verify that the log entries for the last app were ignored. Then,
// clear the serialized log entries. Verify that the log becomes empty. // clear the serialized log entries. Verify that the log becomes empty.
TEST_F(AppInstallEventLogTest, OverflowAddSerializeAndClear) { TEST_F(ArcAppInstallEventLogTest, OverflowAddSerializeAndClear) {
OverflowMaxLogs(); OverflowMaxLogs();
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
event.set_timestamp(i + kMaxLogs + 9); event.set_timestamp(i + ArcAppInstallEventLog::kMaxLogs + 9);
log_->Add(kFirstPackageName, event); log_->Add(kFirstPackageName, event);
} }
EXPECT_EQ(kMaxLogs + 29, log_->total_size()); EXPECT_EQ(ArcAppInstallEventLog::kMaxLogs + 29, log_->total_size());
EXPECT_EQ(30, log_->max_size()); EXPECT_EQ(30, log_->max_size());
log_->Serialize(&report_); log_->Serialize(&report_);
...@@ -291,9 +291,9 @@ TEST_F(AppInstallEventLogTest, OverflowAddSerializeAndClear) { ...@@ -291,9 +291,9 @@ TEST_F(AppInstallEventLogTest, OverflowAddSerializeAndClear) {
// more app. Serialize the log. Add more entries for one of the apps already in // more app. Serialize the log. Add more entries for one of the apps already in
// the log and another app. Clear the log. Verify that the log now contains the // the log and another app. Clear the log. Verify that the log now contains the
// entries added after serialization for the app that was already in the log. // entries added after serialization for the app that was already in the log.
TEST_F(AppInstallEventLogTest, OverflowSerializeAddAndClear) { TEST_F(ArcAppInstallEventLogTest, OverflowSerializeAddAndClear) {
OverflowMaxLogs(); OverflowMaxLogs();
EXPECT_EQ(kMaxLogs + 9, log_->total_size()); EXPECT_EQ(ArcAppInstallEventLog::kMaxLogs + 9, log_->total_size());
EXPECT_EQ(10, log_->max_size()); EXPECT_EQ(10, log_->max_size());
log_->Serialize(&report_); log_->Serialize(&report_);
...@@ -301,11 +301,11 @@ TEST_F(AppInstallEventLogTest, OverflowSerializeAddAndClear) { ...@@ -301,11 +301,11 @@ TEST_F(AppInstallEventLogTest, OverflowSerializeAddAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
event.set_timestamp(i + kMaxLogs + 9); event.set_timestamp(i + ArcAppInstallEventLog::kMaxLogs + 9);
log_->Add(kFirstPackageName, event); log_->Add(kFirstPackageName, event);
} }
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
event.set_timestamp(i + kMaxLogs + 49); event.set_timestamp(i + ArcAppInstallEventLog::kMaxLogs + 49);
log_->Add(kSecondPackageName, event); log_->Add(kSecondPackageName, event);
} }
...@@ -320,37 +320,38 @@ TEST_F(AppInstallEventLogTest, OverflowSerializeAddAndClear) { ...@@ -320,37 +320,38 @@ TEST_F(AppInstallEventLogTest, OverflowSerializeAddAndClear) {
EXPECT_EQ(kFirstPackageName, app_log.package()); EXPECT_EQ(kFirstPackageName, app_log.package());
ASSERT_EQ(20, app_log.logs_size()); ASSERT_EQ(20, app_log.logs_size());
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
EXPECT_EQ(i + kMaxLogs + 9, app_log.logs(i).timestamp()); EXPECT_EQ(i + ArcAppInstallEventLog::kMaxLogs + 9,
app_log.logs(i).timestamp());
} }
} }
// Add 10 log entries for a first app and more entries than the log has capacity // Add 10 log entries for a first app and more entries than the log has capacity
// for for a second app. Verify that the total and maximum log sizes are // for for a second app. Verify that the total and maximum log sizes are
// reported correctly. // reported correctly.
TEST_F(AppInstallEventLogTest, OverflowSingleApp) { TEST_F(ArcAppInstallEventLogTest, OverflowSingleApp) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
log_->Add(kFirstPackageName, event); log_->Add(kFirstPackageName, event);
} }
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(i + 10); event.set_timestamp(i + 10);
log_->Add(kSecondPackageName, event); log_->Add(kSecondPackageName, event);
} }
EXPECT_EQ(10 + kLogCapacity, log_->total_size()); EXPECT_EQ(10 + SingleArcAppInstallEventLog::kLogCapacity, log_->total_size());
EXPECT_EQ(kLogCapacity, log_->max_size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->max_size());
} }
// Create an empty log. Store the log. Verify that no log file is created. // Create an empty log. Store the log. Verify that no log file is created.
TEST_F(AppInstallEventLogTest, Store) { TEST_F(ArcAppInstallEventLogTest, Store) {
log_->Store(); log_->Store();
EXPECT_FALSE(base::PathExists(file_name_)); EXPECT_FALSE(base::PathExists(file_name_));
} }
// Add a log entry. Store the log. Verify that a log file is created. Then, // Add a log entry. Store the log. Verify that a log file is created. Then,
// delete the log file. Store the log. Verify that no log file is created. // delete the log file. Store the log. Verify that no log file is created.
TEST_F(AppInstallEventLogTest, AddStoreAndStore) { TEST_F(ArcAppInstallEventLogTest, AddStoreAndStore) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
event.set_timestamp(0); event.set_timestamp(0);
...@@ -366,7 +367,7 @@ TEST_F(AppInstallEventLogTest, AddStoreAndStore) { ...@@ -366,7 +367,7 @@ TEST_F(AppInstallEventLogTest, AddStoreAndStore) {
// Serialize the log. Clear the serialized log entries. Store the log. Verify // Serialize the log. Clear the serialized log entries. Store the log. Verify
// that no log file is created. // that no log file is created.
TEST_F(AppInstallEventLogTest, SerializeClearAndStore) { TEST_F(ArcAppInstallEventLogTest, SerializeClearAndStore) {
log_->Serialize(&report_); log_->Serialize(&report_);
log_->ClearSerialized(); log_->ClearSerialized();
log_->Store(); log_->Store();
...@@ -376,7 +377,7 @@ TEST_F(AppInstallEventLogTest, SerializeClearAndStore) { ...@@ -376,7 +377,7 @@ TEST_F(AppInstallEventLogTest, SerializeClearAndStore) {
// Add a log entry. Serialize the log. Clear the serialized log entries. Store // Add a log entry. Serialize the log. Clear the serialized log entries. Store
// the log. Verify that a log file is created. Verify that that the log contents // the log. Verify that a log file is created. Verify that that the log contents
// are loaded correctly. // are loaded correctly.
TEST_F(AppInstallEventLogTest, AddSerializeCleaStoreAndLoad) { TEST_F(ArcAppInstallEventLogTest, AddSerializeCleaStoreAndLoad) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
event.set_timestamp(0); event.set_timestamp(0);
...@@ -386,7 +387,7 @@ TEST_F(AppInstallEventLogTest, AddSerializeCleaStoreAndLoad) { ...@@ -386,7 +387,7 @@ TEST_F(AppInstallEventLogTest, AddSerializeCleaStoreAndLoad) {
log_->Store(); log_->Store();
EXPECT_TRUE(base::PathExists(file_name_)); EXPECT_TRUE(base::PathExists(file_name_));
AppInstallEventLog log(file_name_); ArcAppInstallEventLog log(file_name_);
EXPECT_EQ(0, log.total_size()); EXPECT_EQ(0, log.total_size());
EXPECT_EQ(0, log.max_size()); EXPECT_EQ(0, log.max_size());
...@@ -398,7 +399,7 @@ TEST_F(AppInstallEventLogTest, AddSerializeCleaStoreAndLoad) { ...@@ -398,7 +399,7 @@ TEST_F(AppInstallEventLogTest, AddSerializeCleaStoreAndLoad) {
// Populate and store a log. Load the log. Verify that that the log contents are // Populate and store a log. Load the log. Verify that that the log contents are
// loaded correctly. Then, delete the log file. Store the log. Verify that no // loaded correctly. Then, delete the log file. Store the log. Verify that no
// log file is created. // log file is created.
TEST_F(AppInstallEventLogTest, StoreLoadAndStore) { TEST_F(ArcAppInstallEventLogTest, StoreLoadAndStore) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -412,7 +413,7 @@ TEST_F(AppInstallEventLogTest, StoreLoadAndStore) { ...@@ -412,7 +413,7 @@ TEST_F(AppInstallEventLogTest, StoreLoadAndStore) {
log_->Store(); log_->Store();
AppInstallEventLog log(file_name_); ArcAppInstallEventLog log(file_name_);
EXPECT_EQ(20, log.total_size()); EXPECT_EQ(20, log.total_size());
EXPECT_EQ(10, log.max_size()); EXPECT_EQ(10, log.max_size());
...@@ -428,7 +429,7 @@ TEST_F(AppInstallEventLogTest, StoreLoadAndStore) { ...@@ -428,7 +429,7 @@ TEST_F(AppInstallEventLogTest, StoreLoadAndStore) {
// Populate and serialize a log. Store the log. Load the log. Clear serialized // Populate and serialize a log. Store the log. Load the log. Clear serialized
// entries in the loaded log. Verify that no entries are removed. // entries in the loaded log. Verify that no entries are removed.
TEST_F(AppInstallEventLogTest, SerializeStoreLoadAndClear) { TEST_F(ArcAppInstallEventLogTest, SerializeStoreLoadAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -440,7 +441,7 @@ TEST_F(AppInstallEventLogTest, SerializeStoreLoadAndClear) { ...@@ -440,7 +441,7 @@ TEST_F(AppInstallEventLogTest, SerializeStoreLoadAndClear) {
log_->Store(); log_->Store();
AppInstallEventLog log(file_name_); ArcAppInstallEventLog log(file_name_);
EXPECT_EQ(10, log.total_size()); EXPECT_EQ(10, log.total_size());
EXPECT_EQ(10, log.max_size()); EXPECT_EQ(10, log.max_size());
...@@ -461,7 +462,7 @@ TEST_F(AppInstallEventLogTest, SerializeStoreLoadAndClear) { ...@@ -461,7 +462,7 @@ TEST_F(AppInstallEventLogTest, SerializeStoreLoadAndClear) {
// Populate and serialize a log. Store the log. Change the version in the log // Populate and serialize a log. Store the log. Change the version in the log
// file. Load the log. Verify that the log contents are not loaded. // file. Load the log. Verify that the log contents are not loaded.
TEST_F(AppInstallEventLogTest, LoadVersionMismatch) { TEST_F(ArcAppInstallEventLogTest, LoadVersionMismatch) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -483,7 +484,7 @@ TEST_F(AppInstallEventLogTest, LoadVersionMismatch) { ...@@ -483,7 +484,7 @@ TEST_F(AppInstallEventLogTest, LoadVersionMismatch) {
file->Write(0, reinterpret_cast<const char*>(&version), sizeof(version))); file->Write(0, reinterpret_cast<const char*>(&version), sizeof(version)));
file.reset(); file.reset();
AppInstallEventLog log(file_name_); ArcAppInstallEventLog log(file_name_);
EXPECT_EQ(0, log.total_size()); EXPECT_EQ(0, log.total_size());
EXPECT_EQ(0, log.max_size()); EXPECT_EQ(0, log.max_size());
...@@ -494,7 +495,7 @@ TEST_F(AppInstallEventLogTest, LoadVersionMismatch) { ...@@ -494,7 +495,7 @@ TEST_F(AppInstallEventLogTest, LoadVersionMismatch) {
// Add 10 log entries each for two apps. Store the log. Truncate the file to the // Add 10 log entries each for two apps. Store the log. Truncate the file to the
// length of a log containing 10 log entries for one app plus one byte. Load the // length of a log containing 10 log entries for one app plus one byte. Load the
// log. Verify that the log contains 10 logs for one app. // log. Verify that the log contains 10 logs for one app.
TEST_F(AppInstallEventLogTest, LoadTruncated) { TEST_F(ArcAppInstallEventLogTest, LoadTruncated) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -519,7 +520,7 @@ TEST_F(AppInstallEventLogTest, LoadTruncated) { ...@@ -519,7 +520,7 @@ TEST_F(AppInstallEventLogTest, LoadTruncated) {
file->SetLength(size + 1); file->SetLength(size + 1);
file.reset(); file.reset();
AppInstallEventLog log(file_name_); ArcAppInstallEventLog log(file_name_);
EXPECT_EQ(10, log.total_size()); EXPECT_EQ(10, log.total_size());
EXPECT_EQ(10, log.max_size()); EXPECT_EQ(10, log.max_size());
......
// 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_
...@@ -2,13 +2,15 @@ ...@@ -2,13 +2,15 @@
// 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 <stdint.h> #include <stdint.h>
#include "base/files/file.h" #include "base/files/file.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "chrome/browser/chromeos/policy/install_event_log.h"
#include "chrome/browser/chromeos/policy/single_install_event_log.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace em = enterprise_management; namespace em = enterprise_management;
...@@ -17,21 +19,19 @@ namespace policy { ...@@ -17,21 +19,19 @@ namespace policy {
namespace { namespace {
static const int kLogCapacity = 1024;
static const char kPackageName[] = "com.example.app"; static const char kPackageName[] = "com.example.app";
static const int64_t kTimestamp = 12345; static const int64_t kTimestamp = 12345;
static const char kFileName[] = "event.log"; static const char kFileName[] = "event.log";
} // namespace } // namespace
class SingleAppInstallEventLogTest : public testing::Test { class SingleArcAppInstallEventLogTest : public testing::Test {
protected: protected:
SingleAppInstallEventLogTest() {} SingleArcAppInstallEventLogTest() {}
// testing::Test: // testing::Test:
void SetUp() override { void SetUp() override {
log_.reset(new SingleAppInstallEventLog(kPackageName)); log_.reset(new SingleArcAppInstallEventLog(kPackageName));
} }
void VerifyHeader(bool incomplete) { void VerifyHeader(bool incomplete) {
...@@ -50,24 +50,24 @@ class SingleAppInstallEventLogTest : public testing::Test { ...@@ -50,24 +50,24 @@ class SingleAppInstallEventLogTest : public testing::Test {
base::File::FLAG_READ)); base::File::FLAG_READ));
} }
std::unique_ptr<SingleAppInstallEventLog> log_; std::unique_ptr<SingleArcAppInstallEventLog> log_;
em::AppInstallReport report_; em::AppInstallReport report_;
std::unique_ptr<base::ScopedTempDir> temp_dir_; std::unique_ptr<base::ScopedTempDir> temp_dir_;
std::unique_ptr<base::File> file_; std::unique_ptr<base::File> file_;
private: private:
DISALLOW_COPY_AND_ASSIGN(SingleAppInstallEventLogTest); DISALLOW_COPY_AND_ASSIGN(SingleArcAppInstallEventLogTest);
}; };
// Verify that the package name is returned correctly. // Verify that the package name is returned correctly.
TEST_F(SingleAppInstallEventLogTest, GetPackage) { TEST_F(SingleArcAppInstallEventLogTest, GetPackage) {
EXPECT_EQ(kPackageName, log_->package()); EXPECT_EQ(kPackageName, log_->id());
} }
// Do not add any log entries. Serialize the log. Verify that the serialization // Do not add any log entries. Serialize the log. Verify that the serialization
// contains the the correct header data (package name, incomplete flag) and no // contains the the correct header data (package name, incomplete flag) and no
// log entries. // log entries.
TEST_F(SingleAppInstallEventLogTest, SerializeEmpty) { TEST_F(SingleArcAppInstallEventLogTest, SerializeEmpty) {
EXPECT_TRUE(log_->empty()); EXPECT_TRUE(log_->empty());
EXPECT_EQ(0, log_->size()); EXPECT_EQ(0, log_->size());
...@@ -77,7 +77,7 @@ TEST_F(SingleAppInstallEventLogTest, SerializeEmpty) { ...@@ -77,7 +77,7 @@ TEST_F(SingleAppInstallEventLogTest, SerializeEmpty) {
} }
// Add a log entry. Verify that the entry is serialized correctly. // Add a log entry. Verify that the entry is serialized correctly.
TEST_F(SingleAppInstallEventLogTest, AddAndSerialize) { TEST_F(SingleArcAppInstallEventLogTest, AddAndSerialize) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_timestamp(kTimestamp); event.set_timestamp(kTimestamp);
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
...@@ -97,7 +97,7 @@ TEST_F(SingleAppInstallEventLogTest, AddAndSerialize) { ...@@ -97,7 +97,7 @@ TEST_F(SingleAppInstallEventLogTest, AddAndSerialize) {
// Add 10 log entries. Verify that they are serialized correctly. Then, clear // Add 10 log entries. Verify that they are serialized correctly. Then, clear
// the serialized log entries and verify that the log becomes empty. // the serialized log entries and verify that the log becomes empty.
TEST_F(SingleAppInstallEventLogTest, SerializeAndClear) { TEST_F(SingleArcAppInstallEventLogTest, SerializeAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -126,7 +126,7 @@ TEST_F(SingleAppInstallEventLogTest, SerializeAndClear) { ...@@ -126,7 +126,7 @@ TEST_F(SingleAppInstallEventLogTest, SerializeAndClear) {
// Add 10 log entries. Serialize the log. Add 10 more log entries. Clear the // Add 10 log entries. Serialize the log. Add 10 more log entries. Clear the
// serialized log entries. Verify that the log now contains the last 10 entries. // serialized log entries. Verify that the log now contains the last 10 entries.
TEST_F(SingleAppInstallEventLogTest, SerializeAddAndClear) { TEST_F(SingleArcAppInstallEventLogTest, SerializeAddAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
...@@ -161,20 +161,20 @@ TEST_F(SingleAppInstallEventLogTest, SerializeAddAndClear) { ...@@ -161,20 +161,20 @@ TEST_F(SingleAppInstallEventLogTest, SerializeAddAndClear) {
// that the serialization contains the most recent log entries and the // that the serialization contains the most recent log entries and the
// incomplete flag is set. Then, clear the serialized log entries. Verify that // incomplete flag is set. Then, clear the serialized log entries. Verify that
// the log becomes empty and the incomplete flag is unset. // the log becomes empty and the incomplete flag is unset.
TEST_F(SingleAppInstallEventLogTest, OverflowSerializeAndClear) { TEST_F(SingleArcAppInstallEventLogTest, OverflowSerializeAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
log_->Add(event); log_->Add(event);
} }
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->Serialize(&report_); log_->Serialize(&report_);
VerifyHeader(true /* incomplete */); VerifyHeader(true /* incomplete */);
ASSERT_EQ(kLogCapacity, report_.logs_size()); ASSERT_EQ(SingleArcAppInstallEventLog::kLogCapacity, report_.logs_size());
for (int i = 0; i < kLogCapacity; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity; ++i) {
EXPECT_EQ(i + 1, report_.logs(i).timestamp()); EXPECT_EQ(i + 1, report_.logs(i).timestamp());
} }
...@@ -191,22 +191,22 @@ TEST_F(SingleAppInstallEventLogTest, OverflowSerializeAndClear) { ...@@ -191,22 +191,22 @@ TEST_F(SingleAppInstallEventLogTest, OverflowSerializeAndClear) {
// Add more entries than the log has capacity for. Serialize the log. Add one // Add more entries than the log has capacity for. Serialize the log. Add one
// more log entry. Clear the serialized log entries. Verify that the log now // more log entry. Clear the serialized log entries. Verify that the log now
// contains the most recent entry and the incomplete flag is unset. // contains the most recent entry and the incomplete flag is unset.
TEST_F(SingleAppInstallEventLogTest, OverflowSerializeAddAndClear) { TEST_F(SingleArcAppInstallEventLogTest, OverflowSerializeAddAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
log_->Add(event); log_->Add(event);
} }
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->Serialize(&report_); log_->Serialize(&report_);
event.set_timestamp(kLogCapacity + 1); event.set_timestamp(SingleArcAppInstallEventLog::kLogCapacity + 1);
log_->Add(event); log_->Add(event);
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->ClearSerialized(); log_->ClearSerialized();
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
...@@ -216,42 +216,44 @@ TEST_F(SingleAppInstallEventLogTest, OverflowSerializeAddAndClear) { ...@@ -216,42 +216,44 @@ TEST_F(SingleAppInstallEventLogTest, OverflowSerializeAddAndClear) {
log_->Serialize(&report_); log_->Serialize(&report_);
VerifyHeader(false /* incomplete */); VerifyHeader(false /* incomplete */);
ASSERT_EQ(1, report_.logs_size()); ASSERT_EQ(1, report_.logs_size());
EXPECT_EQ(kLogCapacity + 1, report_.logs(0).timestamp()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity + 1,
report_.logs(0).timestamp());
} }
// Add more entries than the log has capacity for. Serialize the log. Add // Add more entries than the log has capacity for. Serialize the log. Add
// exactly as many entries as the log has capacity for. Clear the serialized log // exactly as many entries as the log has capacity for. Clear the serialized log
// entries. Verify that the log now contains the most recent entries and the // entries. Verify that the log now contains the most recent entries and the
// incomplete flag is unset. // incomplete flag is unset.
TEST_F(SingleAppInstallEventLogTest, OverflowSerializeFillAndClear) { TEST_F(SingleArcAppInstallEventLogTest, OverflowSerializeFillAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
log_->Add(event); log_->Add(event);
} }
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->Serialize(&report_); log_->Serialize(&report_);
for (int i = 0; i < kLogCapacity; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity; ++i) {
event.set_timestamp(kLogCapacity + i); event.set_timestamp(SingleArcAppInstallEventLog::kLogCapacity + i);
log_->Add(event); log_->Add(event);
} }
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->ClearSerialized(); log_->ClearSerialized();
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
report_.Clear(); report_.Clear();
log_->Serialize(&report_); log_->Serialize(&report_);
VerifyHeader(false /* incomplete */); VerifyHeader(false /* incomplete */);
ASSERT_EQ(kLogCapacity, report_.logs_size()); ASSERT_EQ(SingleArcAppInstallEventLog::kLogCapacity, report_.logs_size());
for (int i = 0; i < kLogCapacity; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity; ++i) {
EXPECT_EQ(i + kLogCapacity, report_.logs(i).timestamp()); EXPECT_EQ(i + SingleArcAppInstallEventLog::kLogCapacity,
report_.logs(i).timestamp());
} }
} }
...@@ -259,50 +261,51 @@ TEST_F(SingleAppInstallEventLogTest, OverflowSerializeFillAndClear) { ...@@ -259,50 +261,51 @@ TEST_F(SingleAppInstallEventLogTest, OverflowSerializeFillAndClear) {
// entries than the log has capacity for. Clear the serialized log entries. // entries than the log has capacity for. Clear the serialized log entries.
// Verify that the log now contains the most recent entries and the incomplete // Verify that the log now contains the most recent entries and the incomplete
// flag is set. // flag is set.
TEST_F(SingleAppInstallEventLogTest, OverflowSerializeOverflowAndClear) { TEST_F(SingleArcAppInstallEventLogTest, OverflowSerializeOverflowAndClear) {
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
log_->Add(event); log_->Add(event);
} }
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->Serialize(&report_); log_->Serialize(&report_);
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(kLogCapacity + i); event.set_timestamp(SingleArcAppInstallEventLog::kLogCapacity + i);
log_->Add(event); log_->Add(event);
} }
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
log_->ClearSerialized(); log_->ClearSerialized();
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(kLogCapacity, log_->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log_->size());
report_.Clear(); report_.Clear();
log_->Serialize(&report_); log_->Serialize(&report_);
VerifyHeader(true /* incomplete */); VerifyHeader(true /* incomplete */);
ASSERT_EQ(kLogCapacity, report_.logs_size()); ASSERT_EQ(SingleArcAppInstallEventLog::kLogCapacity, report_.logs_size());
for (int i = 0; i < kLogCapacity; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity; ++i) {
EXPECT_EQ(i + kLogCapacity + 1, report_.logs(i).timestamp()); EXPECT_EQ(i + SingleArcAppInstallEventLog::kLogCapacity + 1,
report_.logs(i).timestamp());
} }
} }
// Load log from a file that is not open. Verify that the operation fails. // Load log from a file that is not open. Verify that the operation fails.
TEST_F(SingleAppInstallEventLogTest, FailLoad) { TEST_F(SingleArcAppInstallEventLogTest, FailLoad) {
base::File invalid_file; base::File invalid_file;
std::unique_ptr<SingleAppInstallEventLog> log = std::unique_ptr<SingleArcAppInstallEventLog> log =
std::make_unique<SingleAppInstallEventLog>(kPackageName); std::make_unique<SingleArcAppInstallEventLog>(kPackageName);
EXPECT_FALSE(SingleAppInstallEventLog::Load(&invalid_file, &log)); EXPECT_FALSE(SingleArcAppInstallEventLog::Load(&invalid_file, &log));
EXPECT_FALSE(log); EXPECT_FALSE(log);
} }
// Add a log entry. Store the log to a file that is not open. Verify that the // Add a log entry. Store the log to a file that is not open. Verify that the
// operation fails and the log is not modified. // operation fails and the log is not modified.
TEST_F(SingleAppInstallEventLogTest, FailStore) { TEST_F(SingleArcAppInstallEventLogTest, FailStore) {
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);
...@@ -312,7 +315,7 @@ TEST_F(SingleAppInstallEventLogTest, FailStore) { ...@@ -312,7 +315,7 @@ TEST_F(SingleAppInstallEventLogTest, FailStore) {
base::File invalid_file; base::File invalid_file;
EXPECT_FALSE(log_->Store(&invalid_file)); EXPECT_FALSE(log_->Store(&invalid_file));
EXPECT_EQ(kPackageName, log_->package()); EXPECT_EQ(kPackageName, log_->id());
EXPECT_FALSE(log_->empty()); EXPECT_FALSE(log_->empty());
EXPECT_EQ(1, log_->size()); EXPECT_EQ(1, log_->size());
...@@ -324,16 +327,16 @@ TEST_F(SingleAppInstallEventLogTest, FailStore) { ...@@ -324,16 +327,16 @@ TEST_F(SingleAppInstallEventLogTest, FailStore) {
// Store an empty log. Load the log. Verify that that the log contents are // Store an empty log. Load the log. Verify that that the log contents are
// loaded correctly. // loaded correctly.
TEST_F(SingleAppInstallEventLogTest, StoreEmptyAndLoad) { TEST_F(SingleArcAppInstallEventLogTest, StoreEmptyAndLoad) {
ASSERT_NO_FATAL_FAILURE(CreateFile()); ASSERT_NO_FATAL_FAILURE(CreateFile());
log_->Store(file_.get()); log_->Store(file_.get());
file_->Seek(base::File::FROM_BEGIN, 0); file_->Seek(base::File::FROM_BEGIN, 0);
std::unique_ptr<SingleAppInstallEventLog> log; std::unique_ptr<SingleArcAppInstallEventLog> log;
EXPECT_TRUE(SingleAppInstallEventLog::Load(file_.get(), &log)); EXPECT_TRUE(SingleArcAppInstallEventLog::Load(file_.get(), &log));
ASSERT_TRUE(log); ASSERT_TRUE(log);
EXPECT_EQ(kPackageName, log->package()); EXPECT_EQ(kPackageName, log->id());
EXPECT_TRUE(log->empty()); EXPECT_TRUE(log->empty());
EXPECT_EQ(0, log->size()); EXPECT_EQ(0, log->size());
...@@ -344,7 +347,7 @@ TEST_F(SingleAppInstallEventLogTest, StoreEmptyAndLoad) { ...@@ -344,7 +347,7 @@ TEST_F(SingleAppInstallEventLogTest, StoreEmptyAndLoad) {
// Populate and store a log. Load the log. Verify that that the log contents are // Populate and store a log. Load the log. Verify that that the log contents are
// loaded correctly. // loaded correctly.
TEST_F(SingleAppInstallEventLogTest, StoreAndLoad) { TEST_F(SingleArcAppInstallEventLogTest, StoreAndLoad) {
ASSERT_NO_FATAL_FAILURE(CreateFile()); ASSERT_NO_FATAL_FAILURE(CreateFile());
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
...@@ -357,10 +360,10 @@ TEST_F(SingleAppInstallEventLogTest, StoreAndLoad) { ...@@ -357,10 +360,10 @@ TEST_F(SingleAppInstallEventLogTest, StoreAndLoad) {
log_->Store(file_.get()); log_->Store(file_.get());
file_->Seek(base::File::FROM_BEGIN, 0); file_->Seek(base::File::FROM_BEGIN, 0);
std::unique_ptr<SingleAppInstallEventLog> log; std::unique_ptr<SingleArcAppInstallEventLog> log;
EXPECT_TRUE(SingleAppInstallEventLog::Load(file_.get(), &log)); EXPECT_TRUE(SingleArcAppInstallEventLog::Load(file_.get(), &log));
ASSERT_TRUE(log); ASSERT_TRUE(log);
EXPECT_EQ(kPackageName, log->package()); EXPECT_EQ(kPackageName, log->id());
EXPECT_FALSE(log->empty()); EXPECT_FALSE(log->empty());
EXPECT_EQ(10, log->size()); EXPECT_EQ(10, log->size());
...@@ -374,12 +377,12 @@ TEST_F(SingleAppInstallEventLogTest, StoreAndLoad) { ...@@ -374,12 +377,12 @@ TEST_F(SingleAppInstallEventLogTest, StoreAndLoad) {
// Add more entries than the log has capacity for. Store the log. Load the log. // Add more entries than the log has capacity for. Store the log. Load the log.
// Verify that the log is marked as incomplete. // Verify that the log is marked as incomplete.
TEST_F(SingleAppInstallEventLogTest, OverflowStoreAndLoad) { TEST_F(SingleArcAppInstallEventLogTest, OverflowStoreAndLoad) {
ASSERT_NO_FATAL_FAILURE(CreateFile()); ASSERT_NO_FATAL_FAILURE(CreateFile());
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
event.set_event_type(em::AppInstallReportLogEvent::SUCCESS); event.set_event_type(em::AppInstallReportLogEvent::SUCCESS);
for (int i = 0; i < kLogCapacity + 1; ++i) { for (int i = 0; i < SingleArcAppInstallEventLog::kLogCapacity + 1; ++i) {
event.set_timestamp(i); event.set_timestamp(i);
log_->Add(event); log_->Add(event);
} }
...@@ -387,12 +390,12 @@ TEST_F(SingleAppInstallEventLogTest, OverflowStoreAndLoad) { ...@@ -387,12 +390,12 @@ TEST_F(SingleAppInstallEventLogTest, OverflowStoreAndLoad) {
log_->Store(file_.get()); log_->Store(file_.get());
file_->Seek(base::File::FROM_BEGIN, 0); file_->Seek(base::File::FROM_BEGIN, 0);
std::unique_ptr<SingleAppInstallEventLog> log; std::unique_ptr<SingleArcAppInstallEventLog> log;
EXPECT_TRUE(SingleAppInstallEventLog::Load(file_.get(), &log)); EXPECT_TRUE(SingleArcAppInstallEventLog::Load(file_.get(), &log));
ASSERT_TRUE(log); ASSERT_TRUE(log);
EXPECT_EQ(kPackageName, log->package()); EXPECT_EQ(kPackageName, log->id());
EXPECT_FALSE(log->empty()); EXPECT_FALSE(log->empty());
EXPECT_EQ(kLogCapacity, log->size()); EXPECT_EQ(SingleArcAppInstallEventLog::kLogCapacity, log->size());
log->Serialize(&report_); log->Serialize(&report_);
VerifyHeader(true /* incomplete */); VerifyHeader(true /* incomplete */);
...@@ -400,7 +403,7 @@ TEST_F(SingleAppInstallEventLogTest, OverflowStoreAndLoad) { ...@@ -400,7 +403,7 @@ TEST_F(SingleAppInstallEventLogTest, OverflowStoreAndLoad) {
// Populate and serialize a log. Store the log. Load the log. Clear serialized // Populate and serialize a log. Store the log. Load the log. Clear serialized
// entries in the loaded log. Verify that no entries are removed. // entries in the loaded log. Verify that no entries are removed.
TEST_F(SingleAppInstallEventLogTest, SerializeStoreLoadAndClear) { TEST_F(SingleArcAppInstallEventLogTest, SerializeStoreLoadAndClear) {
ASSERT_NO_FATAL_FAILURE(CreateFile()); ASSERT_NO_FATAL_FAILURE(CreateFile());
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
...@@ -415,10 +418,10 @@ TEST_F(SingleAppInstallEventLogTest, SerializeStoreLoadAndClear) { ...@@ -415,10 +418,10 @@ TEST_F(SingleAppInstallEventLogTest, SerializeStoreLoadAndClear) {
log_->Store(file_.get()); log_->Store(file_.get());
file_->Seek(base::File::FROM_BEGIN, 0); file_->Seek(base::File::FROM_BEGIN, 0);
std::unique_ptr<SingleAppInstallEventLog> log; std::unique_ptr<SingleArcAppInstallEventLog> log;
EXPECT_TRUE(SingleAppInstallEventLog::Load(file_.get(), &log)); EXPECT_TRUE(SingleArcAppInstallEventLog::Load(file_.get(), &log));
ASSERT_TRUE(log); ASSERT_TRUE(log);
EXPECT_EQ(kPackageName, log->package()); EXPECT_EQ(kPackageName, log->id());
EXPECT_FALSE(log->empty()); EXPECT_FALSE(log->empty());
EXPECT_EQ(10, log->size()); EXPECT_EQ(10, log->size());
...@@ -438,7 +441,7 @@ TEST_F(SingleAppInstallEventLogTest, SerializeStoreLoadAndClear) { ...@@ -438,7 +441,7 @@ TEST_F(SingleAppInstallEventLogTest, SerializeStoreLoadAndClear) {
// Add 20 log entries. Store the log. Truncate the file to the length of a log // Add 20 log entries. Store the log. Truncate the file to the length of a log
// containing 10 log entries plus one byte. Load the log. Verify that the log // containing 10 log entries plus one byte. Load the log. Verify that the log
// contains the first 10 log entries and is marked as incomplete. // contains the first 10 log entries and is marked as incomplete.
TEST_F(SingleAppInstallEventLogTest, LoadTruncated) { TEST_F(SingleArcAppInstallEventLogTest, LoadTruncated) {
ASSERT_NO_FATAL_FAILURE(CreateFile()); ASSERT_NO_FATAL_FAILURE(CreateFile());
em::AppInstallReportLogEvent event; em::AppInstallReportLogEvent event;
...@@ -461,10 +464,10 @@ TEST_F(SingleAppInstallEventLogTest, LoadTruncated) { ...@@ -461,10 +464,10 @@ TEST_F(SingleAppInstallEventLogTest, LoadTruncated) {
file_->Seek(base::File::FROM_BEGIN, 0); file_->Seek(base::File::FROM_BEGIN, 0);
file_->SetLength(size + 1); file_->SetLength(size + 1);
std::unique_ptr<SingleAppInstallEventLog> log; std::unique_ptr<SingleArcAppInstallEventLog> log;
EXPECT_FALSE(SingleAppInstallEventLog::Load(file_.get(), &log)); EXPECT_FALSE(SingleArcAppInstallEventLog::Load(file_.get(), &log));
ASSERT_TRUE(log); ASSERT_TRUE(log);
EXPECT_EQ(kPackageName, log->package()); EXPECT_EQ(kPackageName, log->id());
EXPECT_FALSE(log->empty()); EXPECT_FALSE(log->empty());
EXPECT_EQ(10, log->size()); EXPECT_EQ(10, log->size());
......
// 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