// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/ash/enterprise_reporting/history_converter.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h"
#include "chromeos/dbus/missive/history_tracker.h"
#include "components/reporting/proto/synced/health.pb.h"
#include "components/reporting/proto/synced/status.pb.h"
#include "components/reporting/util/status.h"
namespace ash::reporting {
namespace {
std::string StatusFromProto(const ::reporting::StatusProto& source) {
::reporting::Status status;
status.RestoreFrom(source);
return status.ToString();
}
void PopulateStorageQueueAction(
const ::reporting::StorageQueueAction& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest) {
dest.call = "QueueAction";
switch (source.action_case()) {
case ::reporting::StorageQueueAction::ActionCase::kStorageEnqueue:
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"EnqueueSeqId",
base::NumberToString(source.storage_enqueue().sequencing_id())));
break;
case ::reporting::StorageQueueAction::ActionCase::kStorageDequeue:
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"DequeueSeqId",
base::NumberToString(source.storage_dequeue().sequencing_id())));
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"DequeueCount",
base::NumberToString(source.storage_dequeue().records_count())));
break;
default:
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"UnknownAction", ""));
}
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Priority", ::reporting::Priority_Name(source.priority())));
dest.status = StatusFromProto(source.status());
}
void PopulateEnqueueRecord(const ::reporting::EnqueueRecordCall& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest) {
dest.call = "Enqueue";
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Priority", ::reporting::Priority_Name(source.priority())));
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Destination", ::reporting::Destination_Name(source.destination())));
dest.status = StatusFromProto(source.status());
}
void PopulateFlushRecord(const ::reporting::FlushPriorityCall& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest) {
dest.call = "Flush";
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Priority", ::reporting::Priority_Name(source.priority())));
dest.status = StatusFromProto(source.status());
}
void PopulateConfirmRecord(const ::reporting::ConfirmRecordUploadCall& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest) {
dest.call = "Confirm";
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Sequencing_id", base::NumberToString(source.sequencing_id())));
if (source.force_confirm()) {
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Force_confirm", "True"));
}
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Priority", ::reporting::Priority_Name(source.priority())));
dest.status = StatusFromProto(source.status());
}
void PopulateUploadRecord(const ::reporting::UploadEncryptedRecordCall& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest) {
dest.call = "Upload";
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Reason", source.upload_reason()));
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Priority", ::reporting::Priority_Name(source.priority())));
for (const auto& item : source.items()) {
switch (item.item_case()) {
case ::reporting::UploadItem::ItemCase::kRecord:
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Record",
base::StrCat({"seq=", base::NumberToString(
item.record().sequencing_id())})));
break;
case ::reporting::UploadItem::ItemCase::kGap:
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Gap",
base::StrCat(
{"seq=", base::NumberToString(item.gap().sequencing_id()),
" count=", base::NumberToString(item.gap().count())})));
break;
default:
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Unknown", ""));
}
}
dest.status = StatusFromProto(source.status());
}
void PopulateBlockedRecord(const ::reporting::BlockedRecordCall& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest){
dest.call = "BlockedRecord";
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Priority", ::reporting::Priority_Name(source.priority())));
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Destination", ::reporting::Destination_Name(source.destination())));
}
void PopulateBlockedDestinationsUpdated(
const ::reporting::BlockedDestinationsUpdatedCall& source,
enterprise_reporting::mojom::ErpHistoryEvent& dest) {
dest.call = "BlockedDestinations";
for (const auto& item : source.destinations()) {
dest.parameters.emplace_back(
enterprise_reporting::mojom::ErpHistoryEventParameter::New(
"Destination", ::reporting::Destination_Name(item)));
}
}
} // namespace
mojo::StructPtr<enterprise_reporting::mojom::ErpHistoryData> ConvertHistory(
const ::reporting::ERPHealthData& data) {
auto result = enterprise_reporting::mojom::ErpHistoryData::New();
for (const auto& history : data.history()) {
result->events.emplace_back(
enterprise_reporting::mojom::ErpHistoryEvent::New());
result->events.back()->time = history.timestamp_seconds();
switch (history.record_case()) {
case ::reporting::HealthDataHistory::RecordCase::kEnqueueRecordCall:
PopulateEnqueueRecord(history.enqueue_record_call(),
*result->events.back());
break;
case ::reporting::HealthDataHistory::RecordCase::kFlushPriorityCall:
PopulateFlushRecord(history.flush_priority_call(),
*result->events.back());
break;
case ::reporting::HealthDataHistory::RecordCase::
kUploadEncryptedRecordCall:
PopulateUploadRecord(history.upload_encrypted_record_call(),
*result->events.back());
break;
case ::reporting::HealthDataHistory::RecordCase::kConfirmRecordUploadCall:
PopulateConfirmRecord(history.confirm_record_upload_call(),
*result->events.back());
break;
case ::reporting::HealthDataHistory::RecordCase::kStorageQueueAction:
PopulateStorageQueueAction(history.storage_queue_action(),
*result->events.back());
break;
case ::reporting::HealthDataHistory::RecordCase::kBlockedRecordCall:
PopulateBlockedRecord(history.blocked_record_call(),
*result->events.back());
break;
case ::reporting::HealthDataHistory::RecordCase::
kBlockedDestinationsUpdatedCall:
PopulateBlockedDestinationsUpdated(
history.blocked_destinations_updated_call(),
*result->events.back());
break;
default:
result->events.back()->call = "UNKNOWN";
result->events.back()->status = "N/A";
}
}
return result;
}
} // namespace ash::reporting