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

Commit d7e8a534 authored by Mårten Kongstad's avatar Mårten Kongstad Committed by Todd Kennedy
Browse files

idmap2: add debug information to idmap file format

Add a new variable length string to the idmap file format. This string will
hold debug information like fulfilled policies and any warnings triggered while
generating the file.

Bump the idmap version to 3.

Adjust the idmap header definition in ResourceType.h to take the new string
into account.

Example debug info:

  $ idmap2 create \
        --target-apk-path frameworks/base/cmds/idmap2/tests/data/target/target.apk \
        --overlay-apk-path frameworks/base/cmds/idmap2/tests/data/overlay/overlay.apk \
        --idmap-path /tmp/a.idmap \
        --policy public \
        --policy oem

  $ idmap2 dump --idmap-path /tmp/a.idmap
  target apk path  : frameworks/base/cmds/idmap2/tests/data/target/target.apk
  overlay apk path : frameworks/base/cmds/idmap2/tests/data/overlay/overlay.apk
  I fulfilled_policies=oem|public enforce_overlayable=true
  W failed to find resource "integer/not_in_target" in target resources
  0x7f010000 -> 0x7f010000 integer/int1
  0x7f02000c -> 0x7f020000 string/str1
  [...]

  $ idmap2 dump --idmap-path /tmp/a.idmap --verbose
  00000000: 504d4449  magic
  00000004: 00000003  version
  00000008: 76a20829  target crc
  0000000c: c054fb26  overlay crc
  00000010: ........  target path: frameworks/base/cmds/idmap2/tests/data/target/target.apk
  00000110: ........  overlay path: frameworks/base/cmds/idmap2/tests/data/overlay/overlay.apk
  00000210: ........  debug info: ...
  00000294:       7f  target package id
  00000295:       7f  overlay package id
  [...]

Also, tell cpplint to accept non-const references as function parameters:
they make more sense as out-parameters than pointers that are assumed to
be non-null.

Also, switch to regular expressions in the RawPrintVisitorTests: no more
manual fixups of the stream offsets! Tell cpplint that the <regex>
header is OK to use.

Bug: 140790707
Test: idmap2_tests
Change-Id: Ib94684a3b4001240321801e21af8e132fbcf6609
parent d1ee549a
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -15,4 +15,4 @@
set noparent
set noparent
linelength=100
linelength=100
root=..
root=..
filter=+build/include_alpha
filter=+build/include_alpha,-runtime/references,-build/c++
+2 −1
Original line number Original line Diff line number Diff line
@@ -40,7 +40,8 @@ class BinaryStreamVisitor : public Visitor {
  void Write8(uint8_t value);
  void Write8(uint8_t value);
  void Write16(uint16_t value);
  void Write16(uint16_t value);
  void Write32(uint32_t value);
  void Write32(uint32_t value);
  void WriteString(const StringPiece& value);
  void WriteString256(const StringPiece& value);
  void WriteString(const std::string& value);
  std::ostream& stream_;
  std::ostream& stream_;
};
};


+15 −4
Original line number Original line Diff line number Diff line
@@ -18,19 +18,21 @@
 * # idmap file format (current version)
 * # idmap file format (current version)
 *
 *
 * idmap             := header data*
 * idmap             := header data*
 * header            := magic version target_crc overlay_crc target_path overlay_path
 * header            := magic version target_crc overlay_crc target_path overlay_path debug_info
 * data              := data_header data_block*
 * data              := data_header data_block*
 * data_header       := target_package_id types_count
 * data_header       := target_package_id types_count
 * data_block        := target_type overlay_type entry_count entry_offset entry*
 * data_block        := target_type overlay_type entry_count entry_offset entry*
 * overlay_path      := string
 * overlay_path      := string256
 * target_path       := string
 * target_path       := string256
 * debug_info        := string
 * string            := <uint32_t> <uint8_t>+ '\0'+
 * entry             := <uint32_t>
 * entry             := <uint32_t>
 * entry_count       := <uint16_t>
 * entry_count       := <uint16_t>
 * entry_offset      := <uint16_t>
 * entry_offset      := <uint16_t>
 * magic             := <uint32_t>
 * magic             := <uint32_t>
 * overlay_crc       := <uint32_t>
 * overlay_crc       := <uint32_t>
 * overlay_type      := <uint16_t>
 * overlay_type      := <uint16_t>
 * string            := <uint8_t>[256]
 * string256         := <uint8_t>[256]
 * target_crc        := <uint32_t>
 * target_crc        := <uint32_t>
 * target_package_id := <uint16_t>
 * target_package_id := <uint16_t>
 * target_type       := <uint16_t>
 * target_type       := <uint16_t>
@@ -41,6 +43,7 @@
 * # idmap file format changelog
 * # idmap file format changelog
 * ## v1
 * ## v1
 * - Identical to idmap v1.
 * - Identical to idmap v1.
 *
 * ## v2
 * ## v2
 * - Entries are no longer separated by type into type specific data blocks.
 * - Entries are no longer separated by type into type specific data blocks.
 * - Added overlay-indexed target resource id lookup capabilities.
 * - Added overlay-indexed target resource id lookup capabilities.
@@ -53,6 +56,9 @@
 * - Idmap can now encode a type and value to override a resource without needing a table entry.
 * - Idmap can now encode a type and value to override a resource without needing a table entry.
 * - A string pool block is included to retrieve the value of strings that do not have a resource
 * - A string pool block is included to retrieve the value of strings that do not have a resource
 *   table entry.
 *   table entry.
 *
 * ## v3
 * - Add 'debug' block to IdmapHeader.
 */
 */


#ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
#ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
@@ -116,6 +122,10 @@ class IdmapHeader {
    return StringPiece(overlay_path_);
    return StringPiece(overlay_path_);
  }
  }


  inline const std::string& GetDebugInfo() const {
    return debug_info_;
  }

  // Invariant: anytime the idmap data encoding is changed, the idmap version
  // Invariant: anytime the idmap data encoding is changed, the idmap version
  // field *must* be incremented. Because of this, we know that if the idmap
  // field *must* be incremented. Because of this, we know that if the idmap
  // header is up-to-date the entire file is up-to-date.
  // header is up-to-date the entire file is up-to-date.
@@ -133,6 +143,7 @@ class IdmapHeader {
  uint32_t overlay_crc_;
  uint32_t overlay_crc_;
  char target_path_[kIdmapStringLength];
  char target_path_[kIdmapStringLength];
  char overlay_path_[kIdmapStringLength];
  char overlay_path_[kIdmapStringLength];
  std::string debug_info_;


  friend Idmap;
  friend Idmap;
  DISALLOW_COPY_AND_ASSIGN(IdmapHeader);
  DISALLOW_COPY_AND_ASSIGN(IdmapHeader);
+81 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IDMAP2_INCLUDE_IDMAP2_LOGINFO_H_
#define IDMAP2_INCLUDE_IDMAP2_LOGINFO_H_

#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

#if __ANDROID__
#include "android-base/logging.h"
#else
#include <iostream>
#endif

namespace android::idmap2 {

class LogMessage {
 public:
  LogMessage() = default;

  template <typename T>
  LogMessage& operator<<(const T& value) {
    stream_ << value;
    return *this;
  }

  std::string GetString() const {
    return stream_.str();
  }

 private:
  std::stringstream stream_;
};

class LogInfo {
 public:
  LogInfo() = default;

  inline void Info(const LogMessage& msg) {
    lines_.push_back("I " + msg.GetString());
  }

  inline void Warning(const LogMessage& msg) {
#ifdef __ANDROID__
    LOG(WARNING) << msg.GetString();
#else
    std::cerr << "W " << msg.GetString() << std::endl;
#endif
    lines_.push_back("W " + msg.GetString());
  }

  inline std::string GetString() const {
    std::ostringstream stream;
    std::copy(lines_.begin(), lines_.end(), std::ostream_iterator<std::string>(stream, "\n"));
    return stream.str();
  }

 private:
  std::vector<std::string> lines_;
};

}  // namespace android::idmap2

#endif  // IDMAP2_INCLUDE_IDMAP2_LOGINFO_H_
+1 −1
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ class RawPrintVisitor : public Visitor {
  void print(uint8_t value, const char* fmt, ...);
  void print(uint8_t value, const char* fmt, ...);
  void print(uint16_t value, const char* fmt, ...);
  void print(uint16_t value, const char* fmt, ...);
  void print(uint32_t value, const char* fmt, ...);
  void print(uint32_t value, const char* fmt, ...);
  void print(const std::string& value, const char* fmt, ...);
  void print(const std::string& value, size_t encoded_size, const char* fmt, ...);
  void print_raw(uint32_t length, const char* fmt, ...);
  void print_raw(uint32_t length, const char* fmt, ...);


  std::ostream& stream_;
  std::ostream& stream_;
Loading