summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_app_NativeActivity.cpp12
-rw-r--r--libs/androidfw/.clang-format5
-rw-r--r--libs/androidfw/ResourceTypes.cpp85
-rw-r--r--libs/androidfw/tests/Idmap_test.cpp100
-rw-r--r--libs/androidfw/tests/data/overlay/overlay.apkbin1254 -> 2442 bytes
-rw-r--r--libs/androidfw/tests/data/overlay/res/values/values.xml2
-rw-r--r--tools/aapt2/.clang-format6
7 files changed, 131 insertions, 79 deletions
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index fd9e714618e5..ee74ef002407 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -128,8 +128,13 @@ struct NativeCode : public ANativeActivity {
if (callbacks.onDestroy != NULL) {
callbacks.onDestroy(this);
}
- if (env != NULL && clazz != NULL) {
+ if (env != NULL) {
+ if (clazz != NULL) {
env->DeleteGlobalRef(clazz);
+ }
+ if (javaAssetManager != NULL) {
+ env->DeleteGlobalRef(javaAssetManager);
+ }
}
if (messageQueue != NULL && mainWorkRead >= 0) {
messageQueue->getLooper()->removeFd(mainWorkRead);
@@ -170,6 +175,10 @@ struct NativeCode : public ANativeActivity {
int mainWorkRead;
int mainWorkWrite;
sp<MessageQueue> messageQueue;
+
+ // Need to hold on to a reference here in case the upper layers destroy our
+ // AssetManager.
+ jobject javaAssetManager;
};
void android_NativeActivity_finish(ANativeActivity* activity) {
@@ -345,6 +354,7 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName
code->sdkVersion = sdkVersion;
+ code->javaAssetManager = env->NewGlobalRef(jAssetMgr);
code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
if (obbDir != NULL) {
diff --git a/libs/androidfw/.clang-format b/libs/androidfw/.clang-format
index ee1bee2bc644..c91502a257f3 100644
--- a/libs/androidfw/.clang-format
+++ b/libs/androidfw/.clang-format
@@ -1,2 +1,7 @@
BasedOnStyle: Google
ColumnLimit: 100
+AllowShortBlocksOnASingleLine: false
+AllowShortFunctionsOnASingleLine: false
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+PointerAlignment: Left
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 359cface8b7f..244c52577a1a 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -6431,32 +6431,42 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
}
if (newEntryCount > 0) {
+ bool addToType = true;
uint8_t typeIndex = typeSpec->id - 1;
ssize_t idmapIndex = idmapEntries.indexOfKey(typeSpec->id);
if (idmapIndex >= 0) {
typeIndex = idmapEntries[idmapIndex].targetTypeId() - 1;
+ } else if (header->resourceIDMap != NULL) {
+ // This is an overlay, but the types in this overlay are not
+ // overlaying anything according to the idmap. We can skip these
+ // as they will otherwise conflict with the other resources in the package
+ // without a mapping.
+ addToType = false;
}
- TypeList& typeList = group->types.editItemAt(typeIndex);
- if (!typeList.isEmpty()) {
- const Type* existingType = typeList[0];
- if (existingType->entryCount != newEntryCount && idmapIndex < 0) {
- ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
- (int) newEntryCount, (int) existingType->entryCount);
- // We should normally abort here, but some legacy apps declare
- // resources in the 'android' package (old bug in AAPT).
+ if (addToType) {
+ TypeList& typeList = group->types.editItemAt(typeIndex);
+ if (!typeList.isEmpty()) {
+ const Type* existingType = typeList[0];
+ if (existingType->entryCount != newEntryCount && idmapIndex < 0) {
+ ALOGW("ResTable_typeSpec entry count inconsistent: "
+ "given %d, previously %d",
+ (int) newEntryCount, (int) existingType->entryCount);
+ // We should normally abort here, but some legacy apps declare
+ // resources in the 'android' package (old bug in AAPT).
+ }
}
- }
- Type* t = new Type(header, package, newEntryCount);
- t->typeSpec = typeSpec;
- t->typeSpecFlags = (const uint32_t*)(
- ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
- if (idmapIndex >= 0) {
- t->idmapEntries = idmapEntries[idmapIndex];
+ Type* t = new Type(header, package, newEntryCount);
+ t->typeSpec = typeSpec;
+ t->typeSpecFlags = (const uint32_t*)(
+ ((const uint8_t*)typeSpec) + dtohs(typeSpec->header.headerSize));
+ if (idmapIndex >= 0) {
+ t->idmapEntries = idmapEntries[idmapIndex];
+ }
+ typeList.add(t);
+ group->largestTypeId = max(group->largestTypeId, typeSpec->id);
}
- typeList.add(t);
- group->largestTypeId = max(group->largestTypeId, typeSpec->id);
} else {
ALOGV("Skipping empty ResTable_typeSpec for type %d", typeSpec->id);
}
@@ -6499,31 +6509,40 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
}
if (newEntryCount > 0) {
+ bool addToType = true;
uint8_t typeIndex = type->id - 1;
ssize_t idmapIndex = idmapEntries.indexOfKey(type->id);
if (idmapIndex >= 0) {
typeIndex = idmapEntries[idmapIndex].targetTypeId() - 1;
+ } else if (header->resourceIDMap != NULL) {
+ // This is an overlay, but the types in this overlay are not
+ // overlaying anything according to the idmap. We can skip these
+ // as they will otherwise conflict with the other resources in the package
+ // without a mapping.
+ addToType = false;
}
- TypeList& typeList = group->types.editItemAt(typeIndex);
- if (typeList.isEmpty()) {
- ALOGE("No TypeSpec for type %d", type->id);
- return (mError=BAD_TYPE);
- }
+ if (addToType) {
+ TypeList& typeList = group->types.editItemAt(typeIndex);
+ if (typeList.isEmpty()) {
+ ALOGE("No TypeSpec for type %d", type->id);
+ return (mError=BAD_TYPE);
+ }
- Type* t = typeList.editItemAt(typeList.size() - 1);
- if (t->package != package) {
- ALOGE("No TypeSpec for type %d", type->id);
- return (mError=BAD_TYPE);
- }
+ Type* t = typeList.editItemAt(typeList.size() - 1);
+ if (t->package != package) {
+ ALOGE("No TypeSpec for type %d", type->id);
+ return (mError=BAD_TYPE);
+ }
- t->configs.add(type);
+ t->configs.add(type);
- if (kDebugTableGetEntry) {
- ResTable_config thisConfig;
- thisConfig.copyFromDtoH(type->config);
- ALOGI("Adding config to type %d: %s\n", type->id,
- thisConfig.toString().string());
+ if (kDebugTableGetEntry) {
+ ResTable_config thisConfig;
+ thisConfig.copyFromDtoH(type->config);
+ ALOGI("Adding config to type %d: %s\n", type->id,
+ thisConfig.toString().string());
+ }
}
} else {
ALOGV("Skipping empty ResTable_type for type %d", type->id);
diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp
index 0928b1b976c3..d12be184745c 100644
--- a/libs/androidfw/tests/Idmap_test.cpp
+++ b/libs/androidfw/tests/Idmap_test.cpp
@@ -30,25 +30,23 @@ class IdmapTest : public ::testing::Test {
protected:
void SetUp() override {
std::string contents;
- ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk",
- "resources.arsc", &contents));
- ASSERT_EQ(NO_ERROR,
- target_table_.add(contents.data(), contents.size(), 0, true));
-
- ASSERT_TRUE(
- ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk",
- "resources.arsc", &overlay_data_));
+ ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc",
+ &contents));
+ ASSERT_EQ(NO_ERROR, target_table_.add(contents.data(), contents.size(), 0, true));
+
+ ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk",
+ "resources.arsc", &overlay_data_));
ResTable overlay_table;
- ASSERT_EQ(NO_ERROR,
- overlay_table.add(overlay_data_.data(), overlay_data_.size()));
+ ASSERT_EQ(NO_ERROR, overlay_table.add(overlay_data_.data(), overlay_data_.size()));
char target_name[256] = "com.android.basic";
- ASSERT_EQ(NO_ERROR,
- target_table_.createIdmap(overlay_table, 0, 0, target_name,
- target_name, &data_, &data_size_));
+ ASSERT_EQ(NO_ERROR, target_table_.createIdmap(overlay_table, 0, 0, target_name, target_name,
+ &data_, &data_size_));
}
- void TearDown() override { ::free(data_); }
+ void TearDown() override {
+ ::free(data_);
+ }
ResTable target_table_;
std::string overlay_data_;
@@ -56,13 +54,12 @@ class IdmapTest : public ::testing::Test {
size_t data_size_ = 0;
};
-TEST_F(IdmapTest, canLoadIdmap) {
+TEST_F(IdmapTest, CanLoadIdmap) {
ASSERT_EQ(NO_ERROR,
- target_table_.add(overlay_data_.data(), overlay_data_.size(), data_,
- data_size_));
+ target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
}
-TEST_F(IdmapTest, overlayOverridesResourceValue) {
+TEST_F(IdmapTest, OverlayOverridesResourceValue) {
Res_value val;
ssize_t block = target_table_.getResource(R::string::test2, &val, false);
ASSERT_GE(block, 0);
@@ -71,45 +68,60 @@ TEST_F(IdmapTest, overlayOverridesResourceValue) {
ASSERT_TRUE(pool != NULL);
ASSERT_LT(val.data, pool->size());
- size_t strLen;
- const char16_t* targetStr16 = pool->stringAt(val.data, &strLen);
- ASSERT_TRUE(targetStr16 != NULL);
- ASSERT_EQ(String16("test2"), String16(targetStr16, strLen));
+ size_t str_len;
+ const char16_t* target_str16 = pool->stringAt(val.data, &str_len);
+ ASSERT_TRUE(target_str16 != NULL);
+ ASSERT_EQ(String16("test2"), String16(target_str16, str_len));
ASSERT_EQ(NO_ERROR,
- target_table_.add(overlay_data_.data(), overlay_data_.size(), data_,
- data_size_));
+ target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
- ssize_t newBlock = target_table_.getResource(R::string::test2, &val, false);
- ASSERT_GE(newBlock, 0);
- ASSERT_NE(block, newBlock);
+ ssize_t new_block = target_table_.getResource(R::string::test2, &val, false);
+ ASSERT_GE(new_block, 0);
+ ASSERT_NE(block, new_block);
ASSERT_EQ(Res_value::TYPE_STRING, val.dataType);
- pool = target_table_.getTableStringBlock(newBlock);
+ pool = target_table_.getTableStringBlock(new_block);
ASSERT_TRUE(pool != NULL);
ASSERT_LT(val.data, pool->size());
- targetStr16 = pool->stringAt(val.data, &strLen);
- ASSERT_TRUE(targetStr16 != NULL);
- ASSERT_EQ(String16("test2-overlay"), String16(targetStr16, strLen));
+ target_str16 = pool->stringAt(val.data, &str_len);
+ ASSERT_TRUE(target_str16 != NULL);
+ ASSERT_EQ(String16("test2-overlay"), String16(target_str16, str_len));
}
-TEST_F(IdmapTest, overlaidResourceHasSameName) {
+TEST_F(IdmapTest, OverlaidResourceHasSameName) {
ASSERT_EQ(NO_ERROR,
- target_table_.add(overlay_data_.data(), overlay_data_.size(), data_,
- data_size_));
+ target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
+
+ ResTable::resource_name res_name;
+ ASSERT_TRUE(target_table_.getResourceName(R::array::integerArray1, false, &res_name));
+
+ ASSERT_TRUE(res_name.package != NULL);
+ ASSERT_TRUE(res_name.type != NULL);
+ ASSERT_TRUE(res_name.name != NULL);
+
+ EXPECT_EQ(String16("com.android.basic"), String16(res_name.package, res_name.packageLen));
+ EXPECT_EQ(String16("array"), String16(res_name.type, res_name.typeLen));
+ EXPECT_EQ(String16("integerArray1"), String16(res_name.name, res_name.nameLen));
+}
- ResTable::resource_name resName;
- ASSERT_TRUE(
- target_table_.getResourceName(R::array::integerArray1, false, &resName));
+constexpr const uint32_t kNonOverlaidResourceId = 0x7fff0000u;
- ASSERT_TRUE(resName.package != NULL);
- ASSERT_TRUE(resName.type != NULL);
- ASSERT_TRUE(resName.name != NULL);
+TEST_F(IdmapTest, OverlayDoesNotIncludeNonOverlaidResources) {
+ // First check that the resource we're trying to not include when overlaid is present when
+ // the overlay is loaded as a standalone APK.
+ ResTable table;
+ ASSERT_EQ(NO_ERROR, table.add(overlay_data_.data(), overlay_data_.size(), 0, true));
- EXPECT_EQ(String16("com.android.basic"),
- String16(resName.package, resName.packageLen));
- EXPECT_EQ(String16("array"), String16(resName.type, resName.typeLen));
- EXPECT_EQ(String16("integerArray1"), String16(resName.name, resName.nameLen));
+ Res_value val;
+ ssize_t block = table.getResource(kNonOverlaidResourceId, &val, false /*mayBeBag*/);
+ ASSERT_GE(block, 0);
+
+ // Now add the overlay and verify that the unoverlaid resource is gone.
+ ASSERT_EQ(NO_ERROR,
+ target_table_.add(overlay_data_.data(), overlay_data_.size(), data_, data_size_));
+ block = target_table_.getResource(kNonOverlaidResourceId, &val, false /*mayBeBag*/);
+ ASSERT_LT(block, 0);
}
} // namespace
diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk
index e0e054343601..40bf17c5951a 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlay/res/values/values.xml b/libs/androidfw/tests/data/overlay/res/values/values.xml
index 3e1af9878429..8e4417e457d1 100644
--- a/libs/androidfw/tests/data/overlay/res/values/values.xml
+++ b/libs/androidfw/tests/data/overlay/res/values/values.xml
@@ -20,4 +20,6 @@
<item>10</item>
<item>11</item>
</integer-array>
+ <public type="animator" name="unoverlaid" id="0x7fff0000" />
+ <item type="animator" name="unoverlaid">@null</item>
</resources>
diff --git a/tools/aapt2/.clang-format b/tools/aapt2/.clang-format
index 71c5ef2fcda0..c91502a257f3 100644
--- a/tools/aapt2/.clang-format
+++ b/tools/aapt2/.clang-format
@@ -1,3 +1,7 @@
BasedOnStyle: Google
ColumnLimit: 100
-
+AllowShortBlocksOnASingleLine: false
+AllowShortFunctionsOnASingleLine: false
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+PointerAlignment: Left