blob: 3a2b1d3049982c89c5ef6aeb55a5d89a80328f75 [file] [log] [blame]
// Copyright 2022 The Chromium OS 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 <memory>
#include <string>
#include <base/bind.h>
#include <base/callback.h>
#include <base/memory/scoped_refptr.h>
#include <base/memory/singleton.h>
#include <base/strings/strcat.h>
#include <base/strings/string_number_conversions.h>
#include <base/task/bind_post_task.h>
#include "missive/client/empty_dm_token_retriever.h"
#include "missive/client/missive_client.h"
#include "missive/client/report_queue.h"
#include "missive/client/report_queue_configuration.h"
#include "missive/client/report_queue_impl.h"
#include "missive/client/report_queue_provider.h"
#include "missive/proto/record_constants.pb.h"
#include "missive/storage/missive_storage_module.h"
#include "missive/storage/missive_storage_module_delegate_impl.h"
#include "missive/storage/storage_module_interface.h"
#include "missive/util/status.h"
#include "missive/util/statusor.h"
namespace reporting {
class NonChromeReportQueueProvider : public ReportQueueProvider {
public:
NonChromeReportQueueProvider()
: ReportQueueProvider(base::BindRepeating(
[](base::OnceCallback<void(
StatusOr<scoped_refptr<StorageModuleInterface>>)>
storage_created_cb) {
CreateMissiveStorageModule(std::move(storage_created_cb));
})) {}
void ConfigureReportQueue(
std::unique_ptr<ReportQueueConfiguration> configuration,
ReportQueueProvider::ReportQueueConfiguredCallback completion_cb)
override {
// If DM token has already been set (only likely for testing purposes or
// until pre-existing events are migrated over to use event types instead),
// we do nothing and trigger completion callback with report queue config.
if (!configuration->dm_token().empty()) {
std::move(completion_cb).Run(std::move(configuration));
return;
}
if (configuration->event_type() != EventType::kDevice) {
std::move(completion_cb)
.Run(Status(
error::INTERNAL,
base::StrCat({"No DM token retriever found for event type=",
base::NumberToString(static_cast<int>(
configuration->event_type()))})));
return;
}
auto dm_token_retriever = std::make_unique<EmptyDMTokenRetriever>();
std::move(dm_token_retriever)
->RetrieveDMToken(base::BindOnce(
[](std::unique_ptr<ReportQueueConfiguration> configuration,
ReportQueueProvider::ReportQueueConfiguredCallback completion_cb,
StatusOr<std::string> dm_token_result) {
// Trigger completion callback with error if there was an error
// retrieving DM token.
if (!dm_token_result.ok()) {
std::move(completion_cb).Run(dm_token_result.status());
return;
}
// Set DM token in config and trigger completion callback with the
// corresponding result.
auto config_result =
configuration->SetDMToken(dm_token_result.ValueOrDie());
// Fail on error
if (!config_result.ok()) {
std::move(completion_cb).Run(config_result);
return;
}
// Success, run completion callback with updated config
std::move(completion_cb).Run(std::move(configuration));
},
std::move(configuration), std::move(completion_cb)));
}
static ReportQueueProvider* GetInstance() {
return base::Singleton<NonChromeReportQueueProvider>::get();
}
private:
static void CreateMissiveStorageModule(
base::OnceCallback<void(StatusOr<scoped_refptr<StorageModuleInterface>>)>
cb) {
MissiveClient* const missive_client = MissiveClient::Get();
if (!missive_client) {
std::move(cb).Run(Status(
error::FAILED_PRECONDITION,
"Missive Client unavailable, probably has not been initialized"));
return;
}
// Refer to the storage module.
auto missive_storage_module_delegate =
std::make_unique<MissiveStorageModuleDelegateImpl>(
base::BindPostTask(
missive_client->origin_task_runner(),
base::BindRepeating(&MissiveClient::EnqueueRecord,
missive_client->GetWeakPtr())),
base::BindPostTask(
missive_client->origin_task_runner(),
base::BindRepeating(&MissiveClient::Flush,
missive_client->GetWeakPtr())));
auto missive_storage_module = MissiveStorageModule::Create(
std::move(missive_storage_module_delegate));
if (!missive_storage_module) {
std::move(cb).Run(Status(error::FAILED_PRECONDITION,
"Missive Storage Module failed to create"));
return;
}
LOG(WARNING) << "Store reporting data by a Missive daemon";
std::move(cb).Run(missive_storage_module);
return;
}
};
// static
ReportQueueProvider* ReportQueueProvider::GetInstance() {
return NonChromeReportQueueProvider::GetInstance();
}
} // namespace reporting