Commit d9186540 authored by Bartosz Fabianowski's avatar Bartosz Fabianowski Committed by Commit Bot

Add class that holds app push-install event logs

This adds a class that holds push-install event logs for all apps.
The class is not hooked up to anything yet, so no log entries are
read or written.

Bug: b/73277923
Test: unit_tests
Change-Id: Ic95c02d9a47b56492e9ac9ef9f0d8e1ce8aa4ea1
Reviewed-on: https://chromium-review.googlesource.com/916243
Commit-Queue: Bartosz Fabianowski <bartfab@chromium.org>
Reviewed-by: default avatarJulian Pastarmov <pastarmovj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537676}
parent d1f07e92
...@@ -1232,6 +1232,8 @@ source_set("chromeos") { ...@@ -1232,6 +1232,8 @@ 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/auto_enrollment_client.cc", "policy/auto_enrollment_client.cc",
"policy/auto_enrollment_client.h", "policy/auto_enrollment_client.h",
"policy/bluetooth_policy_handler.cc", "policy/bluetooth_policy_handler.cc",
...@@ -1910,6 +1912,7 @@ source_set("unit_tests") { ...@@ -1910,6 +1912,7 @@ source_set("unit_tests") {
"policy/affiliated_cloud_policy_invalidator_unittest.cc", "policy/affiliated_cloud_policy_invalidator_unittest.cc",
"policy/affiliated_invalidation_service_provider_impl_unittest.cc", "policy/affiliated_invalidation_service_provider_impl_unittest.cc",
"policy/android_management_client_unittest.cc", "policy/android_management_client_unittest.cc",
"policy/app_install_event_log_unittest.cc",
"policy/auto_enrollment_client_unittest.cc", "policy/auto_enrollment_client_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",
......
// 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/app_install_event_log.h"
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <memory>
#include "base/files/file.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/policy/single_app_install_event_log.h"
#include "components/policy/proto/device_management_backend.pb.h"
namespace em = enterprise_management;
namespace policy {
namespace {
static const int64_t kLogFileVersion = 1;
static const ssize_t kMaxLogs = 1024;
} // namespace
AppInstallEventLog::AppInstallEventLog(const base::FilePath& file_name)
: file_name_(file_name) {
base::File file(file_name_, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) {
return;
}
int64_t version;
if (file.ReadAtCurrentPos(reinterpret_cast<char*>(&version),
sizeof(version)) != sizeof(version)) {
LOG(WARNING) << "Corrupted app install log.";
return;
}
if (version != kLogFileVersion) {
LOG(WARNING) << "Log file version mismatch.";
return;
}
ssize_t entries;
if (file.ReadAtCurrentPos(reinterpret_cast<char*>(&entries),
sizeof(entries)) != sizeof(entries)) {
LOG(WARNING) << "Corrupted app install log.";
return;
}
for (int i = 0; i < std::min(entries, kMaxLogs); ++i) {
std::unique_ptr<SingleAppInstallEventLog> log;
const bool file_ok = SingleAppInstallEventLog::Load(&file, &log);
const bool log_ok = log && !log->package().empty() &&
logs_.find(log->package()) == logs_.end();
if (!file_ok || !log_ok) {
LOG(WARNING) << "Corrupted app install log.";
}
if (log_ok) {
total_size_ += log->size();
max_size_ = std::max(max_size_, log->size());
logs_[log->package()] = std::move(log);
}
if (!file_ok) {
return;
}
}
if (entries >= kMaxLogs) {
LOG(WARNING) << "Corrupted app install log.";
}
}
AppInstallEventLog::~AppInstallEventLog() {}
void AppInstallEventLog::Add(const std::string& package,
const em::AppInstallReportLogEvent& event) {
if (logs_.size() == kMaxLogs && logs_.find(package) == logs_.end()) {
LOG(WARNING) << "App install log overflow.";
return;
}
auto& log = logs_[package];
if (log == nullptr) {
log.reset(new SingleAppInstallEventLog(package));
}
total_size_ -= log->size();
log->Add(event);
total_size_ += log->size();
max_size_ = std::max(max_size_, log->size());
dirty_ = true;
}
void AppInstallEventLog::Store() {
if (!dirty_) {
return;
}
base::File file(file_name_,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
if (!file.IsValid()) {
LOG(WARNING) << "Unable to store app install log.";
return;
}
if (file.WriteAtCurrentPos(reinterpret_cast<const char*>(&kLogFileVersion),
sizeof(kLogFileVersion)) !=
sizeof(kLogFileVersion)) {
LOG(WARNING) << "Unable to store app install log.";
return;
}
ssize_t entries = logs_.size();
if (file.WriteAtCurrentPos(reinterpret_cast<const char*>(&entries),
sizeof(entries)) != sizeof(entries)) {
LOG(WARNING) << "Unable to store app install log.";
return;
}
for (const auto& log : logs_) {
if (!log.second->Store(&file)) {
LOG(WARNING) << "Unable to store app install log.";
return;
}
}
dirty_ = false;
}
void AppInstallEventLog::Serialize(em::AppInstallReportRequest* report) {
report->Clear();
for (const auto& log : logs_) {
em::AppInstallReport* const report_log = report->add_app_install_report();
log.second->Serialize(report_log);
}
}
void AppInstallEventLog::ClearSerialized() {
int total_size = 0;
max_size_ = 0;
auto log = logs_.begin();
while (log != logs_.end()) {
log->second->ClearSerialized();
if (log->second->empty()) {
log = logs_.erase(log);
} else {
total_size += log->second->size();
max_size_ = std::max(max_size_, log->second->size());
++log;
}
}
if (total_size != total_size_) {
total_size_ = total_size;
dirty_ = true;
}
}
} // 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_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_
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