| // Copyright 2021 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "missive/client/report_queue.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include <base/functional/bind.h> |
| #include <base/functional/callback.h> |
| #include <base/json/json_writer.h> |
| #include <base/logging.h> |
| #include <base/memory/ptr_util.h> |
| #include <base/sequence_checker.h> |
| #include <base/strings/strcat.h> |
| #include <base/time/time.h> |
| #include <base/types/expected.h> |
| #include <base/values.h> |
| |
| #include "missive/analytics/metrics.h" |
| #include "missive/proto/record.pb.h" |
| #include "missive/proto/record_constants.pb.h" |
| #include "missive/util/status.h" |
| #include "missive/util/statusor.h" |
| |
| namespace reporting { |
| |
| namespace { |
| |
| StatusOr<std::string> ValueToJson(base::Value record) { |
| std::string json_record; |
| if (!base::JSONWriter::Write(record, &json_record)) { |
| return base::unexpected( |
| Status(error::INVALID_ARGUMENT, |
| "Provided record was not convertable to a std::string")); |
| } |
| return json_record; |
| } |
| |
| StatusOr<std::string> ProtoToString( |
| std::unique_ptr<const google::protobuf::MessageLite> record) { |
| std::string protobuf_record; |
| if (!record->SerializeToString(&protobuf_record)) { |
| return base::unexpected( |
| Status(error::INVALID_ARGUMENT, |
| "Unabled to serialize record to string. Most likely due to " |
| "unset required fields.")); |
| } |
| return protobuf_record; |
| } |
| |
| void EnqueueResponded(ReportQueue::EnqueueCallback callback, Status status) { |
| const auto res = analytics::Metrics::SendEnumToUMA( |
| /*name=*/ReportQueue::kEnqueueMetricsName, status.code(), |
| error::Code::MAX_VALUE); |
| LOG_IF(ERROR, !res) << "SendEnumToUMA failure, " |
| << ReportQueue::kEnqueueMetricsName << " " |
| << static_cast<int>(status.code()); |
| std::move(callback).Run(status); |
| } |
| } // namespace |
| |
| ReportQueue::~ReportQueue() = default; |
| |
| void ReportQueue::Enqueue(std::string record, |
| Priority priority, |
| ReportQueue::EnqueueCallback callback) const { |
| AddProducedRecord(base::BindOnce( |
| [](std::string record) -> StatusOr<std::string> { |
| return std::move(record); |
| }, |
| std::move(record)), |
| priority, |
| base::BindOnce(&EnqueueResponded, std::move(callback))); |
| } |
| |
| void ReportQueue::Enqueue(base::Value record, |
| Priority priority, |
| ReportQueue::EnqueueCallback callback) const { |
| AddProducedRecord(base::BindOnce(&ValueToJson, std::move(record)), priority, |
| base::BindOnce(&EnqueueResponded, std::move(callback))); |
| } |
| |
| void ReportQueue::Enqueue( |
| std::unique_ptr<const google::protobuf::MessageLite> record, |
| Priority priority, |
| ReportQueue::EnqueueCallback callback) const { |
| AddProducedRecord(base::BindOnce(&ProtoToString, std::move(record)), priority, |
| base::BindOnce(&EnqueueResponded, std::move(callback))); |
| } |
| |
| } // namespace reporting |