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

Add ExtensionInstallEventLogManager class

ExtensionInstallEventLogManager class ties together collection, storage
and upload of extension logs. This is used for event based reporting
for policy based extensions.

Bug: 1092838
Change-Id: Icad7e1dd6bd3994ea983452db1597a0eb655c576
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2247027
Commit-Queue: Swapnil Gupta <swapnilgupta@google.com>
Reviewed-by: default avatarOleg Davydov <burunduk@chromium.org>
Reviewed-by: default avatarSergey Poromov <poromov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781425}
parent 0cb546bc
......@@ -1992,6 +1992,8 @@ source_set("chromeos") {
"policy/extension_install_event_log.h",
"policy/extension_install_event_log_collector.cc",
"policy/extension_install_event_log_collector.h",
"policy/extension_install_event_log_manager.cc",
"policy/extension_install_event_log_manager.h",
"policy/extension_install_event_log_uploader.cc",
"policy/extension_install_event_log_uploader.h",
"policy/extension_install_event_logger.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/policy/extension_install_event_log_manager.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
#include "chrome/browser/profiles/profile.h"
#include "extensions/browser/extension_registry.h"
namespace em = enterprise_management;
namespace policy {
namespace {
// The log file, stored in the user's profile directory.
constexpr base::FilePath::CharType kLogFileName[] =
FILE_PATH_LITERAL("extension_install_log");
// Returns the path to the extension install event log file for |profile|.
base::FilePath GetLogFilePath(const Profile& profile) {
return profile.GetPath().Append(kLogFileName);
}
} // namespace
ExtensionInstallEventLogManager::ExtensionInstallEventLogManager(
LogTaskRunnerWrapper* log_task_runner_wrapper,
ExtensionInstallEventLogUploader* uploader,
Profile* profile)
: InstallEventLogManagerBase(log_task_runner_wrapper, profile),
uploader_(uploader) {
uploader_->SetDelegate(this);
extension_log_upload_ = std::make_unique<ExtensionLogUpload>(this);
log_ = std::make_unique<ExtensionLog>();
base::PostTaskAndReplyWithResult(
log_task_runner_.get(), FROM_HERE,
base::BindOnce(&ExtensionLog::Init, base::Unretained(log_.get()),
GetLogFilePath(*profile)),
base::BindOnce(
&ExtensionInstallEventLogManager::ExtensionLogUpload::OnLogInit,
extension_log_upload_->log_weak_factory_.GetWeakPtr()));
logger_ = std::make_unique<ExtensionInstallEventLogger>(
this, profile, extensions::ExtensionRegistry::Get(profile));
}
ExtensionInstallEventLogManager::~ExtensionInstallEventLogManager() {
extension_log_upload_.reset();
logger_.reset();
uploader_->SetDelegate(nullptr);
log_task_runner_->DeleteSoon(FROM_HERE, std::move(log_));
}
// static
void ExtensionInstallEventLogManager::Clear(
LogTaskRunnerWrapper* log_task_runner_wrapper,
Profile* profile) {
log_task_runner_wrapper->GetTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(
[](const base::FilePath& log_file_path) {
base::DeleteFile(log_file_path, false /* recursive */);
},
GetLogFilePath(*profile)));
}
void ExtensionInstallEventLogManager::Add(
std::set<extensions::ExtensionId> extensions,
const em::ExtensionInstallReportLogEvent& event) {
if (extensions.empty())
return;
base::PostTaskAndReplyWithResult(
log_task_runner_.get(), FROM_HERE,
base::BindOnce(&ExtensionLog::Add, base::Unretained(log_.get()),
std::move(extensions), event),
base::BindOnce(
&ExtensionInstallEventLogManager::ExtensionLogUpload::OnLogChange,
base::Unretained(extension_log_upload_.get())));
}
void ExtensionInstallEventLogManager::SerializeExtensionLogForUpload(
ExtensionInstallEventLogUploader::Delegate::
ExtensionLogSerializationCallback callback) {
base::PostTaskAndReplyWithResult(
log_task_runner_.get(), FROM_HERE,
base::BindOnce(&ExtensionInstallEventLogManager::ExtensionLog::Serialize,
base::Unretained(log_.get())),
base::BindOnce(
&ExtensionInstallEventLogManager::LogUpload::OnSerializeLogDone<
ExtensionInstallEventLogUploader::Delegate::
ExtensionLogSerializationCallback,
em::ExtensionInstallReportRequest>,
extension_log_upload_->log_weak_factory_.GetWeakPtr(),
std::move(callback)));
}
void ExtensionInstallEventLogManager::OnExtensionLogUploadSuccess() {
if (extension_log_upload_->store_scheduled_) {
extension_log_upload_->store_scheduled_ = false;
extension_log_upload_->store_weak_factory_.InvalidateWeakPtrs();
}
extension_log_upload_->upload_requested_ = false;
base::PostTaskAndReplyWithResult(
log_task_runner_.get(), FROM_HERE,
base::BindOnce(&ExtensionInstallEventLogManager::ExtensionLog::
ClearSerializedAndStore,
base::Unretained(log_.get())),
base::BindOnce(
&ExtensionInstallEventLogManager::ExtensionLogUpload::OnLogChange,
extension_log_upload_->log_weak_factory_.GetWeakPtr()));
}
ExtensionInstallEventLogManager::ExtensionLog::ExtensionLog() : InstallLog() {
DETACH_FROM_SEQUENCE(sequence_checker_);
}
ExtensionInstallEventLogManager::ExtensionLog::~ExtensionLog() {}
std::unique_ptr<em::ExtensionInstallReportRequest>
ExtensionInstallEventLogManager::ExtensionLog::Serialize() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CHECK(log_);
auto serialized_log = std::make_unique<em::ExtensionInstallReportRequest>();
log_->Serialize(serialized_log.get());
return serialized_log;
}
ExtensionInstallEventLogManager::ExtensionLogUpload::ExtensionLogUpload(
ExtensionInstallEventLogManager* owner)
: owner_(owner) {}
ExtensionInstallEventLogManager::ExtensionLogUpload::~ExtensionLogUpload() =
default;
void ExtensionInstallEventLogManager::ExtensionLogUpload::StoreLog() {
CHECK(owner_->log_);
store_scheduled_ = false;
owner_->log_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&ExtensionLog::Store,
base::Unretained(owner_->log_.get())));
}
void ExtensionInstallEventLogManager::ExtensionLogUpload::
RequestUploadForUploader() {
owner_->uploader_->RequestUpload();
}
} // namespace policy
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_EXTENSION_INSTALL_EVENT_LOG_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_EXTENSION_INSTALL_EVENT_LOG_MANAGER_H_
#include <memory>
#include <set>
#include "chrome/browser/chromeos/policy/extension_install_event_log.h"
#include "chrome/browser/chromeos/policy/extension_install_event_log_uploader.h"
#include "chrome/browser/chromeos/policy/extension_install_event_logger.h"
#include "chrome/browser/chromeos/policy/install_event_log_manager.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "extensions/common/extension_id.h"
class Profile;
namespace policy {
// Owns an |ExtensionInstallEventLog| for log storage and an
// |ExtensionInstallEventLogger| for log collection. The
// |ExtensionInstallEventLogUploader| is passed to the constructor and must
// outlive |this|.
class ExtensionInstallEventLogManager
: public InstallEventLogManagerBase,
public ExtensionInstallEventLogger::Delegate,
public ExtensionInstallEventLogUploader::Delegate {
public:
// All accesses to the |profile|'s extension install event log file must use
// the same |log_task_runner_wrapper| to ensure correct I/O serialization.
// |uploader| must outlive |this|.
ExtensionInstallEventLogManager(LogTaskRunnerWrapper* log_task_runner_wrapper,
ExtensionInstallEventLogUploader* uploader,
Profile* profile);
// Posts a task to |log_task_runner_| that stores the log to file and destroys
// |log_|. |log_| thus outlives |this| but any pending callbacks are canceled
// by invalidating weak pointers.
~ExtensionInstallEventLogManager() override;
// Clears all data related to the app-install event log for |profile|. Must
// not be called while an |ExtensionInstallEventLogManager| exists for
// |profile|. This method and any other accesses to the |profile|'s extension
// install event log must use the same |log_task_runner_wrapper| to ensure
// correct I/O serialization.
static void Clear(LogTaskRunnerWrapper* log_task_runner_wrapper,
Profile* profile);
// ExtensionInstallEventLogger::Delegate:
void Add(std::set<extensions::ExtensionId> extensions,
const enterprise_management::ExtensionInstallReportLogEvent& event)
override;
// ExtensionInstallEventLogUploader::Delegate:
void SerializeExtensionLogForUpload(
ExtensionInstallEventLogUploader::Delegate::
ExtensionLogSerializationCallback callback) override;
void OnExtensionLogUploadSuccess() override;
private:
// Once created, |ExtensionLog| runs in the background and must be accessed
// and eventually destroyed via |log_task_runner_|. |ExtensionLog| outlives
// its parent and stores the current log to disk in its destructor.
// TODO(crbub/1092387): Remove this class to handle sequence checking in
// ExtensionInstallEventLog.
class ExtensionLog
: public InstallEventLogManagerBase::InstallLog<
enterprise_management::ExtensionInstallReportLogEvent,
ExtensionInstallEventLog> {
public:
ExtensionLog();
// Stores the current log to disk.
~ExtensionLog() override;
// Serializes the log to a protobuf for upload.
std::unique_ptr<enterprise_management::ExtensionInstallReportRequest>
Serialize();
private:
// Ensures that methods are not called from the wrong thread.
SEQUENCE_CHECKER(sequence_checker_);
};
// |ExtensionLogUpload| is owned by |owner_| and |owner_| outlives it.
class ExtensionLogUpload : public InstallEventLogManagerBase::LogUpload {
public:
explicit ExtensionLogUpload(ExtensionInstallEventLogManager* owner);
~ExtensionLogUpload() override;
void StoreLog() override;
void RequestUploadForUploader() override;
private:
ExtensionInstallEventLogManager* owner_;
};
// Uploads logs to the server.
ExtensionInstallEventLogUploader* const uploader_;
// Helper that owns the log store. Once created, must only be accessed via
// |log_task_runner_|. Outlives |this| and ensures the extension log is stored
// to disk in its destructor.
std::unique_ptr<ExtensionLog> log_;
// Collects log events and passes them to |this|.
std::unique_ptr<ExtensionInstallEventLogger> logger_;
// Handles storing the logs and preparing them for upload.
std::unique_ptr<ExtensionLogUpload> extension_log_upload_;
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_EXTENSION_INSTALL_EVENT_LOG_MANAGER_H_
......@@ -40,7 +40,7 @@ class ExtensionInstallEventLogger
public:
// Adds an identical log entry for every extension in |extensions|.
virtual void Add(
const std::set<extensions::ExtensionId>& extensions,
std::set<extensions::ExtensionId> extensions,
const enterprise_management::ExtensionInstallReportLogEvent& event) = 0;
protected:
......
......@@ -74,7 +74,7 @@ class MockExtensionInstallEventLoggerDelegate
MockExtensionInstallEventLoggerDelegate() = default;
MOCK_METHOD2(Add,
void(const std::set<extensions::ExtensionId>& extensions,
void(std::set<extensions::ExtensionId> extensions,
const em::ExtensionInstallReportLogEvent& event));
};
......
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