blob: 0840af5d3adc4f7fc5b93e86c39426664f254f40 [file] [log] [blame]
// 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 "components/query_tiles/internal/proto_conversion.h"
#include <memory>
#include <utility>
#include "base/strings/utf_string_conversions.h"
using TileStatsProto = query_tiles::proto::TileStats;
namespace query_tiles {
namespace {
// Helper method to convert base::Time to integer for serialization. Loses
// precision beyond milliseconds.
int64_t TimeToMilliseconds(const base::Time& time) {
return time.ToDeltaSinceWindowsEpoch().InMilliseconds();
}
// Helper method to convert serialized time as integer to base::Time for
// deserialization. Loses precision beyond milliseconds.
base::Time MillisecondsToTime(int64_t serialized_time_ms) {
return base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromMilliseconds(serialized_time_ms));
}
// Use to convert TileInfo in response proto to the local Tile structure.
void ResponseToTile(
const ResponseTileProto& response,
Tile* tile,
std::map<std::string, ResponseTileProto> sub_tiles_from_response) {
tile->id = response.tile_id();
tile->display_text = response.display_text();
tile->accessibility_text = response.accessibility_text();
tile->query_text = response.query_string();
for (const auto& image : response.tile_images())
tile->image_metadatas.emplace_back(GURL(image.url()));
for (const auto& search_param : response.search_params())
tile->search_params.emplace_back(search_param);
for (const auto& id : response.sub_tile_ids()) {
if (sub_tiles_from_response.count(id)) {
auto sub_tile_from_response = sub_tiles_from_response.at(id);
auto new_sub_tile = std::make_unique<Tile>();
ResponseToTile(sub_tile_from_response, new_sub_tile.get(),
sub_tiles_from_response);
tile->sub_tiles.emplace_back(std::move(new_sub_tile));
}
}
}
} // namespace
void TileToProto(Tile* entry, TileProto* proto) {
DCHECK(entry);
DCHECK(proto);
proto->set_id(entry->id);
proto->set_query_text(entry->query_text);
proto->set_display_text(entry->display_text);
proto->set_accessibility_text(entry->accessibility_text);
// Set ImageMetadatas.
for (auto& image : entry->image_metadatas) {
auto* data = proto->add_image_metadatas();
data->set_url(image.url.spec());
}
for (auto& search_param : entry->search_params) {
auto* param = proto->add_search_params();
*param = search_param;
}
// Set children.
for (auto& subtile : entry->sub_tiles) {
TileToProto(subtile.get(), proto->add_sub_tiles());
}
}
void TileFromProto(TileProto* proto, Tile* entry) {
DCHECK(entry);
DCHECK(proto);
entry->id = proto->id();
entry->query_text = proto->query_text();
entry->display_text = proto->display_text();
entry->accessibility_text = proto->accessibility_text();
for (const auto& image_md : proto->image_metadatas())
entry->image_metadatas.emplace_back(GURL(image_md.url()));
for (const auto& search_param : proto->search_params())
entry->search_params.emplace_back(search_param);
for (int i = 0; i < proto->sub_tiles_size(); i++) {
auto sub_tile_proto = proto->sub_tiles(i);
auto child = std::make_unique<Tile>();
TileFromProto(&sub_tile_proto, child.get());
entry->sub_tiles.emplace_back(std::move(child));
}
}
void TileGroupToProto(TileGroup* group, TileGroupProto* proto) {
proto->set_id(group->id);
proto->set_locale(group->locale);
proto->set_last_updated_time_ms(TimeToMilliseconds(group->last_updated_ts));
for (auto& tile : group->tiles) {
TileToProto(tile.get(), proto->add_tiles());
}
auto& map = *(proto->mutable_tile_stats());
for (auto& entry : group->tile_stats) {
TileStatsProto stats;
stats.set_score(entry.second.score);
stats.set_last_clicked_time_ms(
TimeToMilliseconds(entry.second.last_clicked_time));
map[entry.first] = stats;
}
}
void TileGroupFromProto(TileGroupProto* proto, TileGroup* group) {
group->id = proto->id();
group->locale = proto->locale();
group->last_updated_ts = MillisecondsToTime(proto->last_updated_time_ms());
for (int i = 0; i < proto->tiles().size(); i++) {
auto entry_proto = proto->tiles(i);
auto child = std::make_unique<Tile>();
TileFromProto(&entry_proto, child.get());
group->tiles.emplace_back(std::move(child));
}
for (auto& entry : proto->tile_stats()) {
group->tile_stats[entry.first] =
TileStats(MillisecondsToTime(entry.second.last_clicked_time_ms()),
entry.second.score());
}
}
void TileGroupFromResponse(const ResponseGroupProto& response,
TileGroup* tile_group) {
if (!response.has_tile_group())
return;
std::vector<ResponseTileProto> top_level_tiles;
std::map<std::string, ResponseTileProto> sub_tiles;
tile_group->locale = response.tile_group().locale();
for (const auto& tile : response.tile_group().tiles()) {
if (tile.is_top_level()) {
top_level_tiles.emplace_back(tile);
} else {
sub_tiles[tile.tile_id()] = tile;
}
}
for (const auto& top_level_tile : top_level_tiles) {
auto new_tile = std::make_unique<Tile>();
ResponseToTile(top_level_tile, new_tile.get(), sub_tiles);
tile_group->tiles.emplace_back(std::move(new_tile));
}
}
} // namespace query_tiles