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

Commit 764acc46 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Encoding of <overlayable> and <policy>"

parents f4764351 75e20dda
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -583,7 +583,65 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
          loaded_package->dynamic_package_map_.emplace_back(std::move(package_name),
                                                            dtohl(entry_iter->packageId));
        }
      } break;

      case RES_TABLE_OVERLAYABLE_TYPE: {
        const ResTable_overlayable_header* header =
            child_chunk.header<ResTable_overlayable_header>();
        if (header == nullptr) {
          LOG(ERROR) << "RES_TABLE_OVERLAYABLE_TYPE too small.";
          return {};
        }

        // Iterate over the overlayable policy chunks
        ChunkIterator overlayable_iter(child_chunk.data_ptr(), child_chunk.data_size());
        while (overlayable_iter.HasNext()) {
          const Chunk overlayable_child_chunk = overlayable_iter.Next();

          switch (overlayable_child_chunk.type()) {
            case RES_TABLE_OVERLAYABLE_POLICY_TYPE: {
              const ResTable_overlayable_policy_header* policy_header =
                  overlayable_child_chunk.header<ResTable_overlayable_policy_header>();
              if (policy_header == nullptr) {
                LOG(ERROR) << "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small.";
                return {};
              }

              if ((overlayable_child_chunk.data_size() / sizeof(ResTable_ref))
                  < dtohl(policy_header->entry_count)) {
                LOG(ERROR) <<  "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small to hold entries.";
                return {};
              }

              // Retrieve all the ids belonging to this policy
              std::unordered_set<uint32_t> ids;
              const auto ids_begin =
                  reinterpret_cast<const ResTable_ref*>(overlayable_child_chunk.data_ptr());
              const auto ids_end = ids_begin + dtohl(policy_header->entry_count);
              for (auto id_iter = ids_begin; id_iter != ids_end; ++id_iter) {
                ids.insert(dtohl(id_iter->ident));
              }

              // Add the pairing of overlayable properties to resource ids to the package
              OverlayableInfo overlayable_info;
              overlayable_info.policy_flags = policy_header->policy_flags;
              loaded_package->overlayable_infos_.push_back(std::make_pair(overlayable_info, ids));
              break;
            }

            default:
              LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type());
              break;
          }
        }

        if (overlayable_iter.HadError()) {
          LOG(ERROR) << StringPrintf("Error parsing RES_TABLE_OVERLAYABLE_POLICY_TYPE: %s",
                                     overlayable_iter.GetLastError().c_str());
          if (overlayable_iter.HadFatalError()) {
            return {};
          }
        }
      } break;

      default:
+1 −13
Original line number Diff line number Diff line
@@ -7076,7 +7076,7 @@ public:
        }
    }

    const auto& getTypeMapping() const {
    const std::map<uint8_t, std::set<std::pair<uint32_t, uint32_t>>>& getTypeMapping() const {
        return mTypeMapping->mData;
    }

@@ -7137,9 +7137,6 @@ status_t ResTable::createIdmap(const ResTable& targetResTable,

    const PackageGroup* packageGroup = mPackageGroups[0];

    // the number of resources overlaid that were not explicitly marked overlayable
    size_t forcedOverlayCount = 0u;

    // find the resources that exist in both packages
    auto typeMapping = std::make_unique<IdmapTypeMapping>();
    for (size_t typeIndex = 0; typeIndex < packageGroup->types.size(); ++typeIndex) {
@@ -7170,11 +7167,6 @@ status_t ResTable::createIdmap(const ResTable& targetResTable,
                continue;
            }

            if ((dtohl(typeConfigs->typeSpecFlags[entryIndex]) &
                    ResTable_typeSpec::SPEC_OVERLAYABLE) == 0) {
                ++forcedOverlayCount;
            }

            typeMapping->add(target_resid, overlay_resid);
        }
    }
@@ -7243,10 +7235,6 @@ status_t ResTable::createIdmap(const ResTable& targetResTable,
        typeData += entryCount * 2;
    }

    if (forcedOverlayCount > 0) {
        ALOGW("idmap: overlaid %zu resources not marked overlayable", forcedOverlayCount);
    }

    return NO_ERROR;
}

+3 −1
Original line number Diff line number Diff line
@@ -89,8 +89,10 @@ class ChunkIterator {
        len_(len),
        last_error_(nullptr) {
    CHECK(next_chunk_ != nullptr) << "data can't be nullptr";
    if (len_ != 0) {
      VerifyNextChunk();
    }
  }

  Chunk Next();
  inline bool HasNext() const { return !HadError() && len_ != 0; };
+18 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <memory>
#include <set>
#include <vector>
#include <unordered_set>

#include "android-base/macros.h"

@@ -76,6 +77,10 @@ struct TypeSpec {
// TypeSpecPtr is a managed pointer that knows how to delete itself.
using TypeSpecPtr = util::unique_cptr<TypeSpec>;

struct OverlayableInfo {
  uint32_t policy_flags;
};

class LoadedPackage {
 public:
  class iterator {
@@ -216,6 +221,18 @@ class LoadedPackage {
    }
  }

  // Retrieve the overlayable properties of the specified resource. If the resource is not
  // overlayable, this will return a null pointer.
  const OverlayableInfo* GetOverlayableInfo(uint32_t resid) const {
    for (const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>& overlayable_info_ids
        : overlayable_infos_) {
      if (overlayable_info_ids.second.find(resid) != overlayable_info_ids.second.end()) {
        return &overlayable_info_ids.first;
      }
    }
    return nullptr;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(LoadedPackage);

@@ -233,6 +250,7 @@ class LoadedPackage {
  ByteBucketArray<TypeSpecPtr> type_specs_;
  ByteBucketArray<uint32_t> resource_ids_;
  std::vector<DynamicPackageEntry> dynamic_package_map_;
  std::vector<const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>> overlayable_infos_;
};

// Read-only view into a resource table. This class validates all data
+46 −5
Original line number Diff line number Diff line
@@ -234,7 +234,9 @@ enum {
    RES_TABLE_PACKAGE_TYPE      = 0x0200,
    RES_TABLE_TYPE_TYPE         = 0x0201,
    RES_TABLE_TYPE_SPEC_TYPE    = 0x0202,
    RES_TABLE_LIBRARY_TYPE      = 0x0203
    RES_TABLE_LIBRARY_TYPE      = 0x0203,
    RES_TABLE_OVERLAYABLE_TYPE  = 0x0204,
    RES_TABLE_OVERLAYABLE_POLICY_TYPE = 0x0205,
};

/**
@@ -1354,10 +1356,6 @@ struct ResTable_typeSpec
    enum : uint32_t {
        // Additional flag indicating an entry is public.
        SPEC_PUBLIC = 0x40000000u,

        // Additional flag indicating an entry is overlayable at runtime.
        // Added in Android-P.
        SPEC_OVERLAYABLE = 0x80000000u,
    };
};

@@ -1607,6 +1605,49 @@ struct ResTable_lib_entry
    uint16_t packageName[128];
};

/**
 * Specifies the set of resources that are explicitly allowed to be overlaid by RROs.
 */
struct ResTable_overlayable_header
{
  struct ResChunk_header header;
};

/**
 * Holds a list of resource ids that are protected from being overlaid by a set of policies. If
 * the overlay fulfils at least one of the policies, then the overlay can overlay the list of
 * resources.
 */
struct ResTable_overlayable_policy_header
{
  struct ResChunk_header header;

  enum PolicyFlags {
    // Any overlay can overlay these resources.
    POLICY_PUBLIC = 0x00000001,

    // The overlay must reside of the system partition or must have existed on the system partition
    // before an upgrade to overlay these resources.
    POLICY_SYSTEM_PARTITION = 0x00000002,

    // The overlay must reside of the vendor partition or must have existed on the vendor partition
    // before an upgrade to overlay these resources.
    POLICY_VENDOR_PARTITION = 0x00000004,

    // The overlay must reside of the product partition or must have existed on the product
    // partition before an upgrade to overlay these resources.
    POLICY_PRODUCT_PARTITION = 0x00000008,

    // The overlay must reside of the product services partition or must have existed on the product
    // services partition before an upgrade to overlay these resources.
    POLICY_PRODUCT_SERVICES_PARTITION = 0x00000010,
  };
  uint32_t policy_flags;

  // The number of ResTable_ref that follow this header.
  uint32_t entry_count;
};

struct alignas(uint32_t) Idmap_header {
  // Always 0x504D4449 ('IDMP')
  uint32_t magic;
Loading