Merge "Allow using reserved package IDs" into pi-dev am: 13588dc9e4
am: c323122e93
Change-Id: I0addf146d9519a93bc2f8f73898a3454cb1cfb56
This commit is contained in:
@@ -3504,13 +3504,14 @@ struct ResTable::PackageGroup
|
||||
{
|
||||
PackageGroup(
|
||||
ResTable* _owner, const String16& _name, uint32_t _id,
|
||||
bool appAsLib, bool _isSystemAsset)
|
||||
bool appAsLib, bool _isSystemAsset, bool _isDynamic)
|
||||
: owner(_owner)
|
||||
, name(_name)
|
||||
, id(_id)
|
||||
, largestTypeId(0)
|
||||
, dynamicRefTable(static_cast<uint8_t>(_id), appAsLib)
|
||||
, isSystemAsset(_isSystemAsset)
|
||||
, isDynamic(_isDynamic)
|
||||
{ }
|
||||
|
||||
~PackageGroup() {
|
||||
@@ -3614,6 +3615,7 @@ struct ResTable::PackageGroup
|
||||
// If the package group comes from a system asset. Used in
|
||||
// determining non-system locales.
|
||||
const bool isSystemAsset;
|
||||
const bool isDynamic;
|
||||
};
|
||||
|
||||
ResTable::Theme::Theme(const ResTable& table)
|
||||
@@ -3982,6 +3984,11 @@ inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const
|
||||
return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
|
||||
}
|
||||
|
||||
inline ssize_t ResTable::getResourcePackageIndexFromPackage(uint8_t packageID) const
|
||||
{
|
||||
return ((ssize_t)mPackageMap[packageID])-1;
|
||||
}
|
||||
|
||||
status_t ResTable::add(const void* data, size_t size, const int32_t cookie, bool copyData) {
|
||||
return addInternal(data, size, NULL, 0, false, cookie, copyData);
|
||||
}
|
||||
@@ -4037,7 +4044,7 @@ status_t ResTable::add(ResTable* src, bool isSystemAsset)
|
||||
for (size_t i=0; i < src->mPackageGroups.size(); i++) {
|
||||
PackageGroup* srcPg = src->mPackageGroups[i];
|
||||
PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id,
|
||||
false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset);
|
||||
false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset, srcPg->isDynamic);
|
||||
for (size_t j=0; j<srcPg->packages.size(); j++) {
|
||||
pg->packages.add(srcPg->packages[j]);
|
||||
}
|
||||
@@ -6277,6 +6284,68 @@ bool ResTable::getResourceFlags(uint32_t resID, uint32_t* outFlags) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResTable::isPackageDynamic(uint8_t packageID) const {
|
||||
if (mError != NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
if (packageID == 0) {
|
||||
ALOGW("Invalid package number 0x%08x", packageID);
|
||||
return false;
|
||||
}
|
||||
|
||||
const ssize_t p = getResourcePackageIndexFromPackage(packageID);
|
||||
|
||||
if (p < 0) {
|
||||
ALOGW("Unknown package number 0x%08x", packageID);
|
||||
return false;
|
||||
}
|
||||
|
||||
const PackageGroup* const grp = mPackageGroups[p];
|
||||
if (grp == NULL) {
|
||||
ALOGW("Bad identifier for package number 0x%08x", packageID);
|
||||
return false;
|
||||
}
|
||||
|
||||
return grp->isDynamic;
|
||||
}
|
||||
|
||||
bool ResTable::isResourceDynamic(uint32_t resID) const {
|
||||
if (mError != NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ssize_t p = getResourcePackageIndex(resID);
|
||||
const int t = Res_GETTYPE(resID);
|
||||
const int e = Res_GETENTRY(resID);
|
||||
|
||||
if (p < 0) {
|
||||
if (Res_GETPACKAGE(resID)+1 == 0) {
|
||||
ALOGW("No package identifier for resource number 0x%08x", resID);
|
||||
} else {
|
||||
ALOGW("No known package for resource number 0x%08x", resID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (t < 0) {
|
||||
ALOGW("No type identifier for resource number 0x%08x", resID);
|
||||
return false;
|
||||
}
|
||||
|
||||
const PackageGroup* const grp = mPackageGroups[p];
|
||||
if (grp == NULL) {
|
||||
ALOGW("Bad identifier for resource number 0x%08x", resID);
|
||||
return false;
|
||||
}
|
||||
|
||||
Entry entry;
|
||||
status_t err = getEntry(grp, t, e, NULL, &entry);
|
||||
if (err != NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return grp->isDynamic;
|
||||
}
|
||||
|
||||
static bool keyCompare(const ResTable_sparseTypeEntry& entry , uint16_t entryIdx) {
|
||||
return dtohs(entry.idx) < entryIdx;
|
||||
}
|
||||
@@ -6520,12 +6589,14 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
|
||||
id = targetPackageId;
|
||||
}
|
||||
|
||||
bool isDynamic = false;
|
||||
if (id >= 256) {
|
||||
LOG_ALWAYS_FATAL("Package id out of range");
|
||||
return NO_ERROR;
|
||||
} else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) {
|
||||
// This is a library or a system asset, so assign an ID
|
||||
id = mNextPackageId++;
|
||||
isDynamic = true;
|
||||
}
|
||||
|
||||
PackageGroup* group = NULL;
|
||||
@@ -6553,10 +6624,9 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
|
||||
size_t idx = mPackageMap[id];
|
||||
if (idx == 0) {
|
||||
idx = mPackageGroups.size() + 1;
|
||||
|
||||
char16_t tmpName[sizeof(pkg->name)/sizeof(pkg->name[0])];
|
||||
strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(pkg->name[0]));
|
||||
group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset);
|
||||
group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset, isDynamic);
|
||||
if (group == NULL) {
|
||||
delete package;
|
||||
return (mError=NO_MEMORY);
|
||||
|
||||
@@ -1715,6 +1715,18 @@ public:
|
||||
|
||||
bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const;
|
||||
|
||||
/**
|
||||
* Returns whether or not the package for the given resource has been dynamically assigned.
|
||||
* If the resource can't be found, returns 'false'.
|
||||
*/
|
||||
bool isResourceDynamic(uint32_t resID) const;
|
||||
|
||||
/**
|
||||
* Returns whether or not the given package has been dynamically assigned.
|
||||
* If the package can't be found, returns 'false'.
|
||||
*/
|
||||
bool isPackageDynamic(uint8_t packageID) const;
|
||||
|
||||
/**
|
||||
* Retrieve the value of a resource. If the resource is found, returns a
|
||||
* value >= 0 indicating the table it is in (for use with
|
||||
@@ -2024,6 +2036,7 @@ private:
|
||||
bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false);
|
||||
|
||||
ssize_t getResourcePackageIndex(uint32_t resID) const;
|
||||
ssize_t getResourcePackageIndexFromPackage(uint8_t packageID) const;
|
||||
|
||||
status_t getEntry(
|
||||
const PackageGroup* packageGroup, int typeIndex, int entryIndex,
|
||||
|
||||
@@ -117,8 +117,7 @@ bool Reference::Equals(const Value* value) const {
|
||||
|
||||
bool Reference::Flatten(android::Res_value* out_value) const {
|
||||
const ResourceId resid = id.value_or_default(ResourceId(0));
|
||||
const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId &&
|
||||
resid.package_id() < kAppPackageId;
|
||||
const bool dynamic = resid.is_valid_dynamic() && is_dynamic;
|
||||
|
||||
if (reference_type == Reference::Type::kResource) {
|
||||
if (dynamic) {
|
||||
|
||||
@@ -157,6 +157,7 @@ struct Reference : public BaseItem<Reference> {
|
||||
Maybe<ResourceId> id;
|
||||
Reference::Type reference_type;
|
||||
bool private_reference = false;
|
||||
bool is_dynamic = false;
|
||||
|
||||
Reference();
|
||||
explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
|
||||
|
||||
@@ -131,6 +131,12 @@ struct LinkOptions {
|
||||
// Stable ID options.
|
||||
std::unordered_map<ResourceName, ResourceId> stable_id_map;
|
||||
Maybe<std::string> resource_id_map_path;
|
||||
|
||||
// When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform
|
||||
// treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid.
|
||||
// In order to work around this limitation, we allow the use of traditionally reserved
|
||||
// resource IDs [those between 0x02 and 0x7E].
|
||||
bool allow_reserved_package_id = false;
|
||||
};
|
||||
|
||||
class LinkContext : public IAaptContext {
|
||||
@@ -910,9 +916,7 @@ class LinkCommand {
|
||||
// Capture the shared libraries so that the final resource table can be properly flattened
|
||||
// with support for shared libraries.
|
||||
for (auto& entry : asset_source->GetAssignedPackageIds()) {
|
||||
if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) {
|
||||
final_table_.included_packages_[entry.first] = entry.second;
|
||||
} else if (entry.first == kAppPackageId) {
|
||||
if (entry.first == kAppPackageId) {
|
||||
// Capture the included base feature package.
|
||||
included_feature_base_ = entry.second;
|
||||
} else if (entry.first == kFrameworkPackageId) {
|
||||
@@ -926,6 +930,8 @@ class LinkCommand {
|
||||
// android:versionCode from the framework AndroidManifest.xml.
|
||||
ExtractCompileSdkVersions(asset_source->GetAssetManager());
|
||||
}
|
||||
} else if (asset_source->IsPackageDynamic(entry.first)) {
|
||||
final_table_.included_packages_[entry.first] = entry.second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1610,7 +1616,15 @@ class LinkCommand {
|
||||
// If required, the package name is modifed before flattening, and then modified back
|
||||
// to its original name.
|
||||
ResourceTablePackage* package_to_rewrite = nullptr;
|
||||
if (context_->GetPackageId() > kAppPackageId &&
|
||||
// Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80
|
||||
// or higher] as invalid. In order to work around this limitation, we allow the use
|
||||
// of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the
|
||||
// definition of what a valid "split" package ID is to account for this.
|
||||
const bool isSplitPackage = (options_.allow_reserved_package_id &&
|
||||
context_->GetPackageId() != kAppPackageId &&
|
||||
context_->GetPackageId() != kFrameworkPackageId)
|
||||
|| (!options_.allow_reserved_package_id && context_->GetPackageId() > kAppPackageId);
|
||||
if (isSplitPackage &&
|
||||
included_feature_base_ == make_value(context_->GetCompilationPackage())) {
|
||||
// The base APK is included, and this is a feature split. If the base package is
|
||||
// the same as this package, then we are building an old style Android Instant Apps feature
|
||||
@@ -2165,6 +2179,10 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
|
||||
"Generates a text file containing the resource symbols of the R class in\n"
|
||||
"the specified folder.",
|
||||
&options.generate_text_symbols_path)
|
||||
.OptionalSwitch("--allow-reserved-package-id",
|
||||
"Allows the use of a reserved package ID. This should on be used for\n"
|
||||
"packages with a pre-O min-sdk\n",
|
||||
&options.allow_reserved_package_id)
|
||||
.OptionalSwitch("--auto-add-overlay",
|
||||
"Allows the addition of new resources in overlays without\n"
|
||||
"<add-resource> tags.",
|
||||
@@ -2275,7 +2293,9 @@ int Link(const std::vector<StringPiece>& args, IDiagnostics* diagnostics) {
|
||||
}
|
||||
|
||||
const uint32_t package_id_int = maybe_package_id_int.value();
|
||||
if (package_id_int < kAppPackageId || package_id_int > std::numeric_limits<uint8_t>::max()) {
|
||||
if (package_id_int > std::numeric_limits<uint8_t>::max()
|
||||
|| package_id_int == kFrameworkPackageId
|
||||
|| (!options.allow_reserved_package_id && package_id_int < kAppPackageId)) {
|
||||
context.GetDiagnostics()->Error(
|
||||
DiagMessage() << StringPrintf(
|
||||
"invalid package ID 0x%02x. Must be in the range 0x7f-0xff.", package_id_int));
|
||||
|
||||
@@ -348,6 +348,7 @@ bool ReferenceLinker::LinkReference(const CallSite& callsite, Reference* referen
|
||||
// against libraries without assigned IDs.
|
||||
// Ex: Linking against own resources when building a static library.
|
||||
reference->id = s->id;
|
||||
reference->is_dynamic = s->is_dynamic;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,6 +256,10 @@ std::map<size_t, std::string> AssetManagerSymbolSource::GetAssignedPackageIds()
|
||||
return package_map;
|
||||
}
|
||||
|
||||
bool AssetManagerSymbolSource::IsPackageDynamic(uint32_t packageId) const {
|
||||
return assets_.getResources(false).isPackageDynamic(packageId);
|
||||
}
|
||||
|
||||
static std::unique_ptr<SymbolTable::Symbol> LookupAttributeInTable(
|
||||
const android::ResTable& table, ResourceId id) {
|
||||
// Try as a bag.
|
||||
@@ -359,6 +363,7 @@ std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindByName(
|
||||
} else {
|
||||
s = util::make_unique<SymbolTable::Symbol>();
|
||||
s->id = res_id;
|
||||
s->is_dynamic = table.isResourceDynamic(res_id.id);
|
||||
}
|
||||
|
||||
if (s) {
|
||||
@@ -383,7 +388,6 @@ std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindById(
|
||||
// Exit early and avoid the error logs from AssetManager.
|
||||
return {};
|
||||
}
|
||||
|
||||
const android::ResTable& table = assets_.getResources(false);
|
||||
Maybe<ResourceName> maybe_name = GetResourceName(table, id);
|
||||
if (!maybe_name) {
|
||||
@@ -399,6 +403,7 @@ std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindById(
|
||||
} else {
|
||||
s = util::make_unique<SymbolTable::Symbol>();
|
||||
s->id = id;
|
||||
s->is_dynamic = table.isResourceDynamic(id.id);
|
||||
}
|
||||
|
||||
if (s) {
|
||||
|
||||
@@ -68,6 +68,7 @@ class SymbolTable {
|
||||
Maybe<ResourceId> id;
|
||||
std::shared_ptr<Attribute> attribute;
|
||||
bool is_public = false;
|
||||
bool is_dynamic = false;
|
||||
};
|
||||
|
||||
SymbolTable(NameMangler* mangler);
|
||||
@@ -205,6 +206,7 @@ class AssetManagerSymbolSource : public ISymbolSource {
|
||||
|
||||
bool AddAssetPath(const android::StringPiece& path);
|
||||
std::map<size_t, std::string> GetAssignedPackageIds() const;
|
||||
bool IsPackageDynamic(uint32_t packageId) const;
|
||||
|
||||
std::unique_ptr<SymbolTable::Symbol> FindByName(
|
||||
const ResourceName& name) override;
|
||||
|
||||
Reference in New Issue
Block a user