Loading core/java/android/app/AlertDialog.java +2 −1 Original line number Diff line number Diff line Loading @@ -215,7 +215,8 @@ public class AlertDialog extends Dialog implements DialogInterface { return R.style.Theme_DeviceDefault_Dialog_Alert; } else if (themeResId == THEME_DEVICE_DEFAULT_LIGHT) { return R.style.Theme_DeviceDefault_Light_Dialog_Alert; } else if (themeResId >= 0x01000000) { // start of real resource IDs. } else if (Integer.compareUnsigned(themeResId, 0x01000000) >= 0) { // start of real resource IDs. return themeResId; } else { final TypedValue outValue = new TypedValue(); Loading core/java/android/appwidget/AppWidgetProviderInfo.java +4 −4 Original line number Diff line number Diff line Loading @@ -368,11 +368,11 @@ public class AppWidgetProviderInfo implements Parcelable { try { Resources resources = context.getPackageManager().getResourcesForApplication( providerInfo.applicationInfo); if (resourceId > 0) { if (density <= 0) { density = context.getResources().getDisplayMetrics().densityDpi; if (resourceId != 0) { if (density < 0) { density = 0; } return resources.getDrawableForDensity(resourceId, density); return resources.getDrawableForDensity(resourceId, density, null); } } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { /* ignore */ Loading tools/aapt2/Main.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ namespace aapt { static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. static const char* sMinorVersion = "13"; static const char* sMinorVersion = "14"; int PrintVersion() { std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "." Loading tools/aapt2/cmd/Link.cpp +69 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,62 @@ class LinkContext : public IAaptContext { int min_sdk_version_ = 0; }; // A custom delegate that generates compatible pre-O IDs for use with feature splits. // Feature splits use package IDs > 7f, which in Java (since Java doesn't have unsigned ints) // is interpreted as a negative number. Some verification was wrongly assuming negative values // were invalid. // // This delegate will attempt to masquerade any '@id/' references with ID 0xPPTTEEEE, // where PP > 7f, as 0x7fPPEEEE. Any potential overlapping is verified and an error occurs if such // an overlap exists. class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate { public: FeatureSplitSymbolTableDelegate(IAaptContext* context) : context_(context) { } virtual ~FeatureSplitSymbolTableDelegate() = default; virtual std::unique_ptr<SymbolTable::Symbol> FindByName( const ResourceName& name, const std::vector<std::unique_ptr<ISymbolSource>>& sources) override { std::unique_ptr<SymbolTable::Symbol> symbol = DefaultSymbolTableDelegate::FindByName(name, sources); if (symbol == nullptr) { return {}; } // Check to see if this is an 'id' with the target package. if (name.type == ResourceType::kId && symbol->id) { ResourceId* id = &symbol->id.value(); if (id->package_id() > kAppPackageId) { // Rewrite the resource ID to be compatible pre-O. ResourceId rewritten_id(kAppPackageId, id->package_id(), id->entry_id()); // Check that this doesn't overlap another resource. if (DefaultSymbolTableDelegate::FindById(rewritten_id, sources) != nullptr) { // The ID overlaps, so log a message (since this is a weird failure) and fail. context_->GetDiagnostics()->Error(DiagMessage() << "Failed to rewrite " << name << " for pre-O feature split support"); return {}; } if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "rewriting " << name << " (" << *id << ") -> (" << rewritten_id << ")"); } *id = rewritten_id; } } return symbol; } private: DISALLOW_COPY_AND_ASSIGN(FeatureSplitSymbolTableDelegate); IAaptContext* context_; }; static bool FlattenXml(xml::XmlResource* xml_res, const StringPiece& path, Maybe<size_t> max_sdk_level, bool keep_raw_values, IArchiveWriter* writer, IAaptContext* context) { Loading Loading @@ -1464,6 +1520,19 @@ class LinkCommand { context_->GetExternalSymbols()->PrependSource( util::make_unique<ResourceTableSymbolSource>(&final_table_)); // Workaround for pre-O runtime that would treat negative resource IDs // (any ID with a package ID > 7f) as invalid. Intercept any ID (PPTTEEEE) with PP > 0x7f // and type == 'id', and return the ID 0x7fPPEEEE. IDs don't need to be real resources, they // are just identifiers. if (context_->GetMinSdkVersion() < SDK_O && context_->GetPackageType() == PackageType::kApp) { if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "enabling pre-O feature split ID rewriting"); } context_->GetExternalSymbols()->SetDelegate( util::make_unique<FeatureSplitSymbolTableDelegate>(context_)); } ReferenceLinker linker; if (!linker.Consume(context_, &final_table_)) { context_->GetDiagnostics()->Error(DiagMessage() << "failed linking references"); Loading tools/aapt2/java/JavaClassGenerator.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include "Resource.h" #include "ResourceTable.h" #include "ResourceValues.h" #include "SdkConstants.h" #include "ValueVisitor.h" #include "java/AnnotationProcessor.h" #include "java/ClassDefinition.h" Loading Loading @@ -430,9 +431,15 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso const ResourceEntry& entry, ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method, std::ostream* out_r_txt) { ResourceId real_id = id; if (context_->GetMinSdkVersion() < SDK_O && name.type == ResourceType::kId && id.package_id() > kAppPackageId) { real_id = ResourceId(kAppPackageId, id.package_id(), id.entry_id()); } const std::string field_name = TransformToFieldName(name.entry); std::unique_ptr<ResourceMember> resource_member = util::make_unique<ResourceMember>(field_name, id); util::make_unique<ResourceMember>(field_name, real_id); // Build the comments and annotations for this entry. AnnotationProcessor* processor = resource_member->GetCommentBuilder(); Loading @@ -458,7 +465,7 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso out_class_def->AddMember(std::move(resource_member)); if (out_r_txt != nullptr) { *out_r_txt << "int " << name.type << " " << field_name << " " << id << "\n"; *out_r_txt << "int " << name.type << " " << field_name << " " << real_id << "\n"; } if (out_rewrite_method != nullptr) { Loading Loading
core/java/android/app/AlertDialog.java +2 −1 Original line number Diff line number Diff line Loading @@ -215,7 +215,8 @@ public class AlertDialog extends Dialog implements DialogInterface { return R.style.Theme_DeviceDefault_Dialog_Alert; } else if (themeResId == THEME_DEVICE_DEFAULT_LIGHT) { return R.style.Theme_DeviceDefault_Light_Dialog_Alert; } else if (themeResId >= 0x01000000) { // start of real resource IDs. } else if (Integer.compareUnsigned(themeResId, 0x01000000) >= 0) { // start of real resource IDs. return themeResId; } else { final TypedValue outValue = new TypedValue(); Loading
core/java/android/appwidget/AppWidgetProviderInfo.java +4 −4 Original line number Diff line number Diff line Loading @@ -368,11 +368,11 @@ public class AppWidgetProviderInfo implements Parcelable { try { Resources resources = context.getPackageManager().getResourcesForApplication( providerInfo.applicationInfo); if (resourceId > 0) { if (density <= 0) { density = context.getResources().getDisplayMetrics().densityDpi; if (resourceId != 0) { if (density < 0) { density = 0; } return resources.getDrawableForDensity(resourceId, density); return resources.getDrawableForDensity(resourceId, density, null); } } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) { /* ignore */ Loading
tools/aapt2/Main.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ namespace aapt { static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. static const char* sMinorVersion = "13"; static const char* sMinorVersion = "14"; int PrintVersion() { std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "." Loading
tools/aapt2/cmd/Link.cpp +69 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,62 @@ class LinkContext : public IAaptContext { int min_sdk_version_ = 0; }; // A custom delegate that generates compatible pre-O IDs for use with feature splits. // Feature splits use package IDs > 7f, which in Java (since Java doesn't have unsigned ints) // is interpreted as a negative number. Some verification was wrongly assuming negative values // were invalid. // // This delegate will attempt to masquerade any '@id/' references with ID 0xPPTTEEEE, // where PP > 7f, as 0x7fPPEEEE. Any potential overlapping is verified and an error occurs if such // an overlap exists. class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate { public: FeatureSplitSymbolTableDelegate(IAaptContext* context) : context_(context) { } virtual ~FeatureSplitSymbolTableDelegate() = default; virtual std::unique_ptr<SymbolTable::Symbol> FindByName( const ResourceName& name, const std::vector<std::unique_ptr<ISymbolSource>>& sources) override { std::unique_ptr<SymbolTable::Symbol> symbol = DefaultSymbolTableDelegate::FindByName(name, sources); if (symbol == nullptr) { return {}; } // Check to see if this is an 'id' with the target package. if (name.type == ResourceType::kId && symbol->id) { ResourceId* id = &symbol->id.value(); if (id->package_id() > kAppPackageId) { // Rewrite the resource ID to be compatible pre-O. ResourceId rewritten_id(kAppPackageId, id->package_id(), id->entry_id()); // Check that this doesn't overlap another resource. if (DefaultSymbolTableDelegate::FindById(rewritten_id, sources) != nullptr) { // The ID overlaps, so log a message (since this is a weird failure) and fail. context_->GetDiagnostics()->Error(DiagMessage() << "Failed to rewrite " << name << " for pre-O feature split support"); return {}; } if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "rewriting " << name << " (" << *id << ") -> (" << rewritten_id << ")"); } *id = rewritten_id; } } return symbol; } private: DISALLOW_COPY_AND_ASSIGN(FeatureSplitSymbolTableDelegate); IAaptContext* context_; }; static bool FlattenXml(xml::XmlResource* xml_res, const StringPiece& path, Maybe<size_t> max_sdk_level, bool keep_raw_values, IArchiveWriter* writer, IAaptContext* context) { Loading Loading @@ -1464,6 +1520,19 @@ class LinkCommand { context_->GetExternalSymbols()->PrependSource( util::make_unique<ResourceTableSymbolSource>(&final_table_)); // Workaround for pre-O runtime that would treat negative resource IDs // (any ID with a package ID > 7f) as invalid. Intercept any ID (PPTTEEEE) with PP > 0x7f // and type == 'id', and return the ID 0x7fPPEEEE. IDs don't need to be real resources, they // are just identifiers. if (context_->GetMinSdkVersion() < SDK_O && context_->GetPackageType() == PackageType::kApp) { if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "enabling pre-O feature split ID rewriting"); } context_->GetExternalSymbols()->SetDelegate( util::make_unique<FeatureSplitSymbolTableDelegate>(context_)); } ReferenceLinker linker; if (!linker.Consume(context_, &final_table_)) { context_->GetDiagnostics()->Error(DiagMessage() << "failed linking references"); Loading
tools/aapt2/java/JavaClassGenerator.cpp +9 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include "Resource.h" #include "ResourceTable.h" #include "ResourceValues.h" #include "SdkConstants.h" #include "ValueVisitor.h" #include "java/AnnotationProcessor.h" #include "java/ClassDefinition.h" Loading Loading @@ -430,9 +431,15 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso const ResourceEntry& entry, ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method, std::ostream* out_r_txt) { ResourceId real_id = id; if (context_->GetMinSdkVersion() < SDK_O && name.type == ResourceType::kId && id.package_id() > kAppPackageId) { real_id = ResourceId(kAppPackageId, id.package_id(), id.entry_id()); } const std::string field_name = TransformToFieldName(name.entry); std::unique_ptr<ResourceMember> resource_member = util::make_unique<ResourceMember>(field_name, id); util::make_unique<ResourceMember>(field_name, real_id); // Build the comments and annotations for this entry. AnnotationProcessor* processor = resource_member->GetCommentBuilder(); Loading @@ -458,7 +465,7 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso out_class_def->AddMember(std::move(resource_member)); if (out_r_txt != nullptr) { *out_r_txt << "int " << name.type << " " << field_name << " " << id << "\n"; *out_r_txt << "int " << name.type << " " << field_name << " " << real_id << "\n"; } if (out_rewrite_method != nullptr) { Loading