diff options
-rw-r--r-- | core/java/android/view/View.java | 2 | ||||
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 4 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/ResourceTypes.h | 2 | ||||
-rw-r--r-- | tests/FeatureSplit/feature1/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | tests/FeatureSplit/feature1/res/layout/included.xml | 5 | ||||
-rw-r--r-- | tests/FeatureSplit/feature1/res/layout/main.xml | 8 | ||||
-rw-r--r-- | tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java | 9 | ||||
-rw-r--r-- | tests/FeatureSplit/feature2/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | tools/aapt2/Debug.cpp | 8 | ||||
-rw-r--r-- | tools/aapt2/flatten/TableFlattener.cpp | 11 | ||||
-rw-r--r-- | tools/aapt2/flatten/TableFlattener_test.cpp | 22 | ||||
-rw-r--r-- | tools/aapt2/flatten/XmlFlattener_test.cpp | 59 | ||||
-rw-r--r-- | tools/aapt2/test/Context.h | 12 |
13 files changed, 124 insertions, 22 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d42c6db106fd..04310fc88377 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -21067,7 +21067,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @Nullable public final <T extends View> T findViewById(@IdRes int id) { - if (id < 0) { + if (id == NO_ID) { return null; } return findViewTraversal(id); diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 09840a575609..f661f29bb7f9 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -6664,6 +6664,10 @@ status_t DynamicRefTable::addMapping(const String16& packageName, uint8_t packag return NO_ERROR; } +void DynamicRefTable::addMapping(uint8_t buildPackageId, uint8_t runtimePackageId) { + mLookupTable[buildPackageId] = runtimePackageId; +} + status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const { uint32_t res = *resId; size_t packageId = Res_GETPACKAGE(res) + 1; diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 306ff9a7c42c..7a6e37d41b7c 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -1610,6 +1610,8 @@ public: // the given package. status_t addMapping(const String16& packageName, uint8_t packageId); + void addMapping(uint8_t buildPackageId, uint8_t runtimePackageId); + // Performs the actual conversion of build-time resource ID to run-time // resource ID. status_t lookupResourceId(uint32_t* resId) const; diff --git a/tests/FeatureSplit/feature1/AndroidManifest.xml b/tests/FeatureSplit/feature1/AndroidManifest.xml index 42619b623e10..b87361faac62 100644 --- a/tests/FeatureSplit/feature1/AndroidManifest.xml +++ b/tests/FeatureSplit/feature1/AndroidManifest.xml @@ -16,7 +16,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test.split.feature" - featureName="feature1"> + featureSplit="feature1"> <uses-sdk android:minSdkVersion="21" /> diff --git a/tests/FeatureSplit/feature1/res/layout/included.xml b/tests/FeatureSplit/feature1/res/layout/included.xml new file mode 100644 index 000000000000..c64bdb7ff85f --- /dev/null +++ b/tests/FeatureSplit/feature1/res/layout/included.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> diff --git a/tests/FeatureSplit/feature1/res/layout/main.xml b/tests/FeatureSplit/feature1/res/layout/main.xml new file mode 100644 index 000000000000..dbea42ab23d0 --- /dev/null +++ b/tests/FeatureSplit/feature1/res/layout/main.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <include layout="@layout/included" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</FrameLayout> diff --git a/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java b/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java index def133919f90..61ac9dfba1cb 100644 --- a/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java +++ b/tests/FeatureSplit/feature1/src/com/android/test/split/feature/one/One.java @@ -15,17 +15,16 @@ */ package com.android.test.split.feature.one; -import com.android.test.split.feature.ActivityMain; - +import android.app.Activity; import android.widget.TextView; import android.os.Bundle; -public class One extends ActivityMain { +public class One extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ((TextView) findViewById(com.android.test.split.feature.R.id.text)) - .setText(R.string.feature_string); + setContentView(R.layout.main); + ((TextView) findViewById(R.id.text)).setText(R.string.feature_string); } } diff --git a/tests/FeatureSplit/feature2/AndroidManifest.xml b/tests/FeatureSplit/feature2/AndroidManifest.xml index b50044ac37b7..abd0b5eb6933 100644 --- a/tests/FeatureSplit/feature2/AndroidManifest.xml +++ b/tests/FeatureSplit/feature2/AndroidManifest.xml @@ -16,7 +16,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test.split.feature" - featureName="feature2"> + featureSplit="feature2"> <uses-sdk android:minSdkVersion="21" /> diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 60b01e372d7b..b872ebbeb159 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -274,7 +274,13 @@ class XmlPrinter : public xml::Visitor { if (!attr.namespace_uri.empty()) { std::cerr << attr.namespace_uri << ":"; } - std::cerr << attr.name << "=" << attr.value << "\n"; + std::cerr << attr.name; + + if (attr.compiled_attribute) { + std::cerr << "(" << attr.compiled_attribute.value().id.value_or_default(ResourceId(0x0)) + << ")"; + } + std::cerr << "=" << attr.value << "\n"; } const size_t previous_size = prefix_.size(); diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp index d44b3e095c0f..f4d02262f25c 100644 --- a/tools/aapt2/flatten/TableFlattener.cpp +++ b/tools/aapt2/flatten/TableFlattener.cpp @@ -573,10 +573,17 @@ bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { // Write the ResTable header. ChunkWriter table_writer(buffer_); - ResTable_header* table_header = - table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE); + ResTable_header* table_header = table_writer.StartChunk<ResTable_header>(RES_TABLE_TYPE); table_header->packageCount = util::HostToDevice32(table->packages.size()); + // Write a self mapping entry for this package if the ID is non-standard (0x7f). + if (context->GetPackageType() == PackageType::kApp) { + const uint8_t package_id = context->GetPackageId(); + if (package_id != kFrameworkPackageId && package_id != kAppPackageId) { + table->included_packages_[package_id] = context->GetCompilationPackage(); + } + } + // Flatten the values string pool. StringPool::FlattenUtf8(table_writer.buffer(), table->string_pool); diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp index 8dff3a27b79f..6d1350d433a4 100644 --- a/tools/aapt2/flatten/TableFlattener_test.cpp +++ b/tools/aapt2/flatten/TableFlattener_test.cpp @@ -400,7 +400,7 @@ TEST_F(TableFlattenerTest, FlattenTableReferencingSharedLibraries) { const DynamicRefTable* dynamic_ref_table = result.getDynamicRefTableForCookie(1); ASSERT_NE(nullptr, dynamic_ref_table); - const KeyedVector<String16, uint8_t> entries = dynamic_ref_table->entries(); + const KeyedVector<String16, uint8_t>& entries = dynamic_ref_table->entries(); ssize_t idx = entries.indexOfKey(android::String16("lib_one")); ASSERT_GE(idx, 0); @@ -411,6 +411,26 @@ TEST_F(TableFlattenerTest, FlattenTableReferencingSharedLibraries) { EXPECT_EQ(0x03u, entries.valueAt(idx)); } +TEST_F(TableFlattenerTest, PackageWithNonStandardIdHasDynamicRefTable) { + std::unique_ptr<IAaptContext> context = + test::ContextBuilder().SetCompilationPackage("app").SetPackageId(0x80).Build(); + std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() + .SetPackageId("app", 0x80) + .AddSimple("app:id/foo", ResourceId(0x80010000)) + .Build(); + + ResTable result; + ASSERT_TRUE(Flatten(context.get(), {}, table.get(), &result)); + + const DynamicRefTable* dynamic_ref_table = result.getDynamicRefTableForCookie(1); + ASSERT_NE(nullptr, dynamic_ref_table); + + const KeyedVector<String16, uint8_t>& entries = dynamic_ref_table->entries(); + ssize_t idx = entries.indexOfKey(android::String16("app")); + ASSERT_GE(idx, 0); + EXPECT_EQ(0x80u, entries.valueAt(idx)); +} + TEST_F(TableFlattenerTest, LongPackageNameIsTruncated) { std::string kPackageName(256, 'F'); diff --git a/tools/aapt2/flatten/XmlFlattener_test.cpp b/tools/aapt2/flatten/XmlFlattener_test.cpp index 494d9d25b008..f0613e74b5f8 100644 --- a/tools/aapt2/flatten/XmlFlattener_test.cpp +++ b/tools/aapt2/flatten/XmlFlattener_test.cpp @@ -35,13 +35,16 @@ class XmlFlattenerTest : public ::testing::Test { .SetNameManglerPolicy(NameManglerPolicy{"com.app.test"}) .AddSymbolSource( test::StaticSymbolSourceBuilder() - .AddSymbol("android:attr/id", ResourceId(0x010100d0), - test::AttributeBuilder().Build()) + .AddPublicSymbol("android:attr/id", ResourceId(0x010100d0), + test::AttributeBuilder().Build()) .AddSymbol("com.app.test:id/id", ResourceId(0x7f020000)) .AddPublicSymbol("android:attr/paddingStart", ResourceId(0x010103b3), test::AttributeBuilder().Build()) .AddPublicSymbol("android:attr/colorAccent", ResourceId(0x01010435), test::AttributeBuilder().Build()) + .AddSymbol("com.app.test.feature:id/foo", ResourceId(0x80020000)) + .AddSymbol("com.app.test.feature:attr/foo", ResourceId(0x80010000), + test::AttributeBuilder().Build()) .Build()) .Build(); } @@ -65,7 +68,7 @@ class XmlFlattenerTest : public ::testing::Test { } protected: - std::unique_ptr<IAaptContext> context_; + std::unique_ptr<test::Context> context_; }; TEST_F(XmlFlattenerTest, FlattenXmlWithNoCompiledAttributes) { @@ -218,14 +221,10 @@ TEST_F(XmlFlattenerTest, AssignSpecialAttributeIndices) { EXPECT_EQ(tree.indexOfStyle(), 1); } -/* - * The device ResXMLParser in libandroidfw differentiates between empty - * namespace and null - * namespace. - */ +// The device ResXMLParser in libandroidfw differentiates between empty namespace and null +// namespace. TEST_F(XmlFlattenerTest, NoNamespaceIsNotTheSameAsEmptyNamespace) { - std::unique_ptr<xml::XmlResource> doc = - test::BuildXmlDom("<View package=\"android\"/>"); + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom("<View package=\"android\"/>"); android::ResXMLTree tree; ASSERT_TRUE(Flatten(doc.get(), &tree)); @@ -261,4 +260,44 @@ TEST_F(XmlFlattenerTest, EmptyStringValueInAttributeIsNotNull) { EXPECT_NE(nullptr, tree.getAttributeStringValue(idx, &len)); } +TEST_F(XmlFlattenerTest, FlattenNonStandardPackageId) { + context_->SetCompilationPackage("com.app.test.feature"); + context_->SetPackageId(0x80); + context_->SetNameManglerPolicy({"com.app.test.feature"}); + + std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDomForPackageName(context_.get(), R"EOF( + <View xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@id/foo" + app:foo="@id/foo" />)EOF"); + + XmlReferenceLinker linker; + ASSERT_TRUE(linker.Consume(context_.get(), doc.get())); + + // The tree needs a custom DynamicRefTable since it is not using a standard app ID (0x7f). + android::DynamicRefTable dynamic_ref_table; + dynamic_ref_table.addMapping(0x80, 0x80); + + android::ResXMLTree tree(&dynamic_ref_table); + ASSERT_TRUE(Flatten(doc.get(), &tree)); + + while (tree.next() != android::ResXMLTree::START_TAG) { + ASSERT_NE(android::ResXMLTree::BAD_DOCUMENT, tree.getEventType()); + ASSERT_NE(android::ResXMLTree::END_DOCUMENT, tree.getEventType()); + } + + ssize_t idx; + + idx = tree.indexOfAttribute(xml::kSchemaAndroid, "id"); + ASSERT_GE(idx, 0); + EXPECT_EQ(idx, tree.indexOfID()); + EXPECT_EQ(ResourceId(0x010100d0), ResourceId(tree.getAttributeNameResID(idx))); + + idx = tree.indexOfAttribute(xml::kSchemaAuto, "foo"); + ASSERT_GE(idx, 0); + EXPECT_EQ(ResourceId(0x80010000), ResourceId(tree.getAttributeNameResID(idx))); + EXPECT_EQ(android::Res_value::TYPE_REFERENCE, tree.getAttributeDataType(idx)); + EXPECT_EQ(ResourceId(0x80020000), tree.getAttributeData(idx)); +} + } // namespace aapt diff --git a/tools/aapt2/test/Context.h b/tools/aapt2/test/Context.h index 29d183876c4c..0564db063b9a 100644 --- a/tools/aapt2/test/Context.h +++ b/tools/aapt2/test/Context.h @@ -52,15 +52,27 @@ class Context : public IAaptContext { return compilation_package_.value(); } + void SetCompilationPackage(const android::StringPiece& package) { + compilation_package_ = package.to_string(); + } + uint8_t GetPackageId() override { CHECK(bool(package_id_)) << "package ID not set"; return package_id_.value(); } + void SetPackageId(uint8_t package_id) { + package_id_ = package_id; + } + NameMangler* GetNameMangler() override { return &name_mangler_; } + void SetNameManglerPolicy(const NameManglerPolicy& policy) { + name_mangler_ = NameMangler(policy); + } + bool IsVerbose() override { return false; } |