Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8200d406 authored by Jeremy Meyer's avatar Jeremy Meyer Committed by Android (Google) Code Review
Browse files

Merge "Store frro configs in idmap file"

parents 3226bed7 be2b7797
Loading
Loading
Loading
Loading
+58 −38
Original line number Diff line number Diff line
@@ -21,12 +21,16 @@
 * header                     := magic version target_crc overlay_crc fulfilled_policies
 *                               enforce_overlayable target_path overlay_path overlay_name
 *                               debug_info
 * data                       := data_header target_entry* target_inline_entry* overlay_entry*
 *                               string_pool
 * data_header                := target_entry_count target_inline_entry_count overlay_entry_count
 * data                       := data_header target_entry* target_inline_entry*
                                 target_inline_entry_value* config* overlay_entry* string_pool
 * data_header                := target_entry_count target_inline_entry_count
                                 target_inline_entry_value_count config_count overlay_entry_count
 *                               string_pool_index
 * target_entry               := target_id overlay_id
 * target_inline_entry        := target_id Res_value::size padding(1) Res_value::type
 * target_inline_entry        := target_id start_value_index value_count
 * target_inline_entry_value  := config_index Res_value::size padding(1) Res_value::type
 *                               Res_value::value
 * config                     := target_id Res_value::size padding(1) Res_value::type
 *                               Res_value::value
 * overlay_entry              := overlay_id target_id
 *
@@ -51,6 +55,11 @@
 * target_crc                       := <uint32_t>
 * target_entry_count               := <uint32_t>
 * target_inline_entry_count        := <uint32_t>
 * target_inline_entry_value_count  := <uint32_t>
 * config_count                     := <uint32_t>
 * config_index                     := <uint32_t>
 * start_value_index                := <uint32_t>
 * value_count                      := <uint32_t>
 * target_id                        := <uint32_t>
 * target_package_id                := <uint8_t>
 * target_path                      := string
@@ -70,6 +79,7 @@
#include "android-base/macros.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "androidfw/ConfigDescription.h"
#include "idmap2/ResourceContainer.h"
#include "idmap2/ResourceMapping.h"

@@ -165,19 +175,27 @@ class IdmapData {
   public:
    static std::unique_ptr<const Header> FromBinaryStream(std::istream& stream);

    inline uint32_t GetTargetEntryCount() const {
    [[nodiscard]] inline uint32_t GetTargetEntryCount() const {
      return target_entry_count;
    }

    inline uint32_t GetTargetInlineEntryCount() const {
    [[nodiscard]] inline uint32_t GetTargetInlineEntryCount() const {
      return target_entry_inline_count;
    }

    inline uint32_t GetOverlayEntryCount() const {
    [[nodiscard]] inline uint32_t GetTargetInlineEntryValueCount() const {
      return target_entry_inline_value_count;
    }

    [[nodiscard]] inline uint32_t GetConfigCount() const {
      return config_count;
    }

    [[nodiscard]] inline uint32_t GetOverlayEntryCount() const {
      return overlay_entry_count;
    }

    inline uint32_t GetStringPoolIndexOffset() const {
    [[nodiscard]] inline uint32_t GetStringPoolIndexOffset() const {
      return string_pool_index_offset;
    }

@@ -186,6 +204,8 @@ class IdmapData {
   private:
    uint32_t target_entry_count;
    uint32_t target_entry_inline_count;
    uint32_t target_entry_inline_value_count;
    uint32_t config_count;
    uint32_t overlay_entry_count;
    uint32_t string_pool_index_offset;
    Header() = default;
@@ -202,7 +222,7 @@ class IdmapData {

  struct TargetInlineEntry {
    ResourceId target_id;
    TargetValue value;
    std::map<ConfigDescription, TargetValue> values;
  };

  struct OverlayEntry {
@@ -227,11 +247,11 @@ class IdmapData {
    return target_inline_entries_;
  }

  const std::vector<OverlayEntry>& GetOverlayEntries() const {
  [[nodiscard]] const std::vector<OverlayEntry>& GetOverlayEntries() const {
    return overlay_entries_;
  }

  const std::string& GetStringPoolData() const {
  [[nodiscard]] const std::string& GetStringPoolData() const {
    return string_pool_data_;
  }

+2 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@
using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;

namespace android::idmap2 {
using TargetResourceMap = std::map<ResourceId, std::variant<ResourceId, TargetValue>>;
using ConfigMap = std::unordered_map<std::string, TargetValue>;
using TargetResourceMap = std::map<ResourceId, std::variant<ResourceId, ConfigMap>>;
using OverlayResourceMap = std::map<ResourceId, ResourceId>;

class ResourceMapping {
+4 −0
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ struct TargetValue {
struct TargetValueWithConfig {
  TargetValue value;
  std::string config;

  [[nodiscard]] std::pair<std::string, TargetValue> to_pair() const {
    return std::make_pair(config, value);
  }
};

namespace utils {
+27 −2
Original line number Diff line number Diff line
@@ -70,12 +70,35 @@ void BinaryStreamVisitor::visit(const IdmapData& data) {
  }

  static constexpr uint16_t kValueSize = 8U;
  std::vector<std::pair<ConfigDescription, TargetValue>> target_values;
  target_values.reserve(data.GetHeader()->GetTargetInlineEntryValueCount());
  for (const auto& target_entry : data.GetTargetInlineEntries()) {
    Write32(target_entry.target_id);
    Write32(target_values.size());
    Write32(target_entry.values.size());
    target_values.insert(
        target_values.end(), target_entry.values.begin(), target_entry.values.end());
  }

  std::vector<ConfigDescription> configs;
  configs.reserve(data.GetHeader()->GetConfigCount());
  for (const auto& target_entry_value : target_values) {
    auto config_it = find(configs.begin(), configs.end(), target_entry_value.first);
    if (config_it != configs.end()) {
      Write32(config_it - configs.begin());
    } else {
      Write32(configs.size());
      configs.push_back(target_entry_value.first);
    }
    Write16(kValueSize);
    Write8(0U);  // padding
    Write8(target_entry.value.data_type);
    Write32(target_entry.value.data_value);
    Write8(target_entry_value.second.data_type);
    Write32(target_entry_value.second.data_value);
  }

  for( auto& cd : configs) {
    cd.swapHtoD();
    stream_.write(reinterpret_cast<char*>(&cd), sizeof(cd));
  }

  for (const auto& overlay_entry : data.GetOverlayEntries()) {
@@ -89,6 +112,8 @@ void BinaryStreamVisitor::visit(const IdmapData& data) {
void BinaryStreamVisitor::visit(const IdmapData::Header& header) {
  Write32(header.GetTargetEntryCount());
  Write32(header.GetTargetInlineEntryCount());
  Write32(header.GetTargetInlineEntryValueCount());
  Write32(header.GetConfigCount());
  Write32(header.GetOverlayEntryCount());
  Write32(header.GetStringPoolIndexOffset());
}
+61 −9
Original line number Diff line number Diff line
@@ -186,6 +186,8 @@ std::unique_ptr<const IdmapData::Header> IdmapData::Header::FromBinaryStream(std
  std::unique_ptr<IdmapData::Header> idmap_data_header(new IdmapData::Header());
  if (!Read32(stream, &idmap_data_header->target_entry_count) ||
      !Read32(stream, &idmap_data_header->target_entry_inline_count) ||
      !Read32(stream, &idmap_data_header->target_entry_inline_value_count) ||
      !Read32(stream, &idmap_data_header->config_count) ||
      !Read32(stream, &idmap_data_header->overlay_entry_count) ||
      !Read32(stream, &idmap_data_header->string_pool_index_offset)) {
    return nullptr;
@@ -207,20 +209,59 @@ std::unique_ptr<const IdmapData> IdmapData::FromBinaryStream(std::istream& strea
    if (!Read32(stream, &target_entry.target_id) || !Read32(stream, &target_entry.overlay_id)) {
      return nullptr;
    }
    data->target_entries_.push_back(target_entry);
    data->target_entries_.emplace_back(target_entry);
  }

  // Read the mapping of target resource id to inline overlay values.
  uint8_t unused1;
  uint16_t unused2;
  std::vector<std::tuple<TargetInlineEntry, uint32_t, uint32_t>> target_inline_entries;
  for (size_t i = 0; i < data->header_->GetTargetInlineEntryCount(); i++) {
    TargetInlineEntry target_entry{};
    if (!Read32(stream, &target_entry.target_id) || !Read16(stream, &unused2) ||
        !Read8(stream, &unused1) || !Read8(stream, &target_entry.value.data_type) ||
        !Read32(stream, &target_entry.value.data_value)) {
    uint32_t entry_offset;
    uint32_t entry_count;
    if (!Read32(stream, &target_entry.target_id) || !Read32(stream, &entry_offset)
        || !Read32(stream, &entry_count)) {
      return nullptr;
    }
    target_inline_entries.emplace_back(std::make_tuple(target_entry, entry_offset, entry_count));
  }

  // Read the inline overlay resource values
  std::vector<std::pair<uint32_t, TargetValue>> target_values;
  uint8_t unused1;
  uint16_t unused2;
  for (size_t i = 0; i < data->header_->GetTargetInlineEntryValueCount(); i++) {
    uint32_t config_index;
    if (!Read32(stream, &config_index)) {
      return nullptr;
    }
    TargetValue value;
    if (!Read16(stream, &unused2)
        || !Read8(stream, &unused1)
        || !Read8(stream, &value.data_type)
        || !Read32(stream, &value.data_value)) {
      return nullptr;
    }
    target_values.emplace_back(std::make_pair(config_index, value));
  }

  // Read the configurations
  std::vector<ConfigDescription> configurations;
  for (size_t i = 0; i < data->header_->GetConfigCount(); i++) {
    ConfigDescription cd;
    if (!stream.read(reinterpret_cast<char*>(&cd), sizeof(ConfigDescription))) {
      return nullptr;
    }
    data->target_inline_entries_.push_back(target_entry);
    configurations.emplace_back(cd);
  }

  // Construct complete target inline entries
  for (auto [target_entry, entry_offset, entry_count] : target_inline_entries) {
    for(size_t i = 0; i < entry_count; i++) {
      const auto& target_value = target_values[entry_offset + i];
      const auto& config = configurations[target_value.first];
      target_entry.values[config] = target_value.second;
    }
    data->target_inline_entries_.emplace_back(target_entry);
  }

  // Read the mapping of overlay resource id to target resource id.
@@ -278,12 +319,21 @@ Result<std::unique_ptr<const IdmapData>> IdmapData::FromResourceMapping(

  std::unique_ptr<IdmapData> data(new IdmapData());
  data->string_pool_data_ = resource_mapping.GetStringPoolData().to_string();
  uint32_t inline_value_count = 0;
  std::set<std::string> config_set;
  for (const auto& mapping : resource_mapping.GetTargetToOverlayMap()) {
    if (auto overlay_resource = std::get_if<ResourceId>(&mapping.second)) {
      data->target_entries_.push_back({mapping.first, *overlay_resource});
    } else {
      data->target_inline_entries_.push_back(
          {mapping.first, std::get<TargetValue>(mapping.second)});
      std::map<ConfigDescription, TargetValue> values;
      for (const auto& [config, value] : std::get<ConfigMap>(mapping.second)) {
        config_set.insert(config);
        ConfigDescription cd;
        ConfigDescription::Parse(config, &cd);
        values[cd] = value;
        inline_value_count++;
      }
      data->target_inline_entries_.push_back({mapping.first, values});
    }
  }

@@ -295,6 +345,8 @@ Result<std::unique_ptr<const IdmapData>> IdmapData::FromResourceMapping(
  data_header->target_entry_count = static_cast<uint32_t>(data->target_entries_.size());
  data_header->target_entry_inline_count =
      static_cast<uint32_t>(data->target_inline_entries_.size());
  data_header->target_entry_inline_value_count = inline_value_count;
  data_header->config_count = config_set.size();
  data_header->overlay_entry_count = static_cast<uint32_t>(data->overlay_entries_.size());
  data_header->string_pool_index_offset = resource_mapping.GetStringPoolOffset();
  data->header_ = std::move(data_header);
Loading