Commit Graph

3 Commits

Author SHA1 Message Date
Eric Miao
368cd19d03 androidfw: Add support for compact resource entries
Bug: 237583012

Given the large number of simple resources such as strings in
Android resources, their ResTable_entry and Res_value can be
encoded together in a compact way.  This allows a significant
saving in both storage and memory footprint.

The basic observations for simple resources are:

* ResTable_entry.size will always be sizeof(ResTable_entry)
  unless it's a complex entry

* ResTable_entry.key is unlikely to exceed 16-bit

* ResTable_entry.flags only uses 3 bits for now

* Res_value.size will always be sizeof(Res_value)

Given the above, we could well encode the information into
a compact/compatible structure.

  struct compact {
      uint16_t key;
      uint16_t flags;
      uint32_t data;
  };

The layout of this structure will allow maximum backward
compatibility. e.g. the flags will be at the same offset,
and a

  `dtohs((ResTable_entry *)entry->flags) & FLAG_COMPACT`

would tell if this entry is a compact one or not. For a
compact entry:

  struct compact *entry;

  entry_size  == sizeof(*entry)
  entry_key   == static_cast<uint32_t>(dtohs(entry->key))
  entry_flags == dtohs(entry->flags) & 0xff	// low 8-bit
  data_type   == dtohs(entry->flags) >> 8	// high 8-bit
  data_size   == sizeof(Res_value)
  data_value  == dtohl(entry->data)

To allow minimum code change and backward compatibility,
we change 'struct ResTable_entry' to 'union ResTable_entry',
with an anonymous structure inside that's fully backward
compatible. Thus, any existing reference such as:

  ResTable_entry *entry = ...
  if (dtohs(entry->flags) & ResTable_entry::FLAG_COMPLEX) ...

would still work.

However, special care needs to be taken after an entry is
obtained, and when value needs to be extracted.

A compact entry will not encode a complex value, and hence
complex entries/values are handled the same way.

Change-Id: I15d97a4f5e85fab28c075496f7f0cf6b1fcd73e3
2022-11-15 12:12:33 -08:00
Iurii Makhno
8b33e7adb8 Add deduplicate_entry_values mode to TableFlattener.
This CL introduces DeduplicateItemsResEntryWriter which stores unique
pairs of entry and value and deduplicates a new pair based of this data
before writing it into the buffer.

Bug: b/249793372
Test: ResEntriesWriter_test, TableFlattener_test
Change-Id: I938a3425a87bfad9853e59193680de2050a95bd2
2022-10-05 12:31:24 +00:00
Iurii Makhno
cf844a3e8c Intoduce ResEntryWriter unit.
ResEntryWriter is responsible to write pairs of entry+value into binary
buffers and allows easy customization how and where entries are written.

This is no-op refactoring and all existing tests should pass.

Bug: b/249793372
Test: Existing tests
Change-Id: Ica98a25aeb49cc96cad28547c462b36316a8adb6
2022-10-05 00:04:31 +00:00