Enforce overlayable API when defined
If a package defines overlayable resources, then do not allow resources
that are not defined as overlayable to be overlaid.
Bug:123600120
Test: idmap2_tests and cts-tradefed run cts -m CtsRROTestCases
Change-Id: I35120a97ccf4650e67c7ba65a60f4f3c51b0e627
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 803f83c..056add5 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -16,11 +16,11 @@
name: "idmap2_defaults",
tidy: true,
tidy_checks: [
+ "modernize-*",
+ "-modernize-avoid-c-arrays",
"android-*",
"misc-*",
- "modernize-*",
"readability-*",
- "-modernize-avoid-c-arrays",
],
tidy_flags: [
"-system-headers",
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 5d449e9..fa5ac8e 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -281,10 +281,10 @@
if (overlayable_info == nullptr) {
// If the resource does not have an overlayable definition, allow the resource to be overlaid.
// Once overlayable enforcement is turned on, this check will return false.
- return true;
+ return !target_package.DefinesOverlayable();
}
- if (!overlay_info.target_name.empty() && overlay_info.target_name != overlayable_info->name) {
+ if (overlay_info.target_name != overlayable_info->name) {
// If the overlay supplies a target overlayable name, the resource must belong to the
// overlayable defined with the specified name to be overlaid.
return false;
diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp
index 45f84fe..8514e12 100644
--- a/cmds/idmap2/tests/FileUtilsTests.cpp
+++ b/cmds/idmap2/tests/FileUtilsTests.cpp
@@ -40,9 +40,14 @@
const std::string& path ATTRIBUTE_UNUSED) -> bool { return true; });
ASSERT_THAT(v, NotNull());
ASSERT_EQ(v->size(), 6U);
- ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
- std::set<std::string>({root + "/.", root + "/..", root + "/overlay", root + "/target",
- root + "/system-overlay", root + "/system-overlay-invalid"}));
+ ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>({
+ root + "/.",
+ root + "/..",
+ root + "/overlay",
+ root + "/target",
+ root + "/system-overlay",
+ root + "/system-overlay-invalid",
+ }));
}
TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) {
@@ -51,13 +56,15 @@
return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0;
});
ASSERT_THAT(v, NotNull());
- ASSERT_EQ(v->size(), 6U);
- ASSERT_EQ(std::set<std::string>(v->begin(), v->end()),
- std::set<std::string>({root + "/target/target.apk", root + "/overlay/overlay.apk",
- root + "/overlay/overlay-static-1.apk",
- root + "/overlay/overlay-static-2.apk",
- root + "/system-overlay/system-overlay.apk",
- root + "/system-overlay-invalid/system-overlay-invalid.apk"}));
+ ASSERT_EQ(v->size(), 9U);
+ ASSERT_EQ(
+ std::set<std::string>(v->begin(), v->end()),
+ std::set<std::string>(
+ {root + "/target/target.apk", root + "/target/target-no-overlayable.apk",
+ root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk",
+ root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-static-1.apk",
+ root + "/overlay/overlay-static-2.apk", root + "/system-overlay/system-overlay.apk",
+ root + "/system-overlay-invalid/system-overlay-invalid.apk"}));
}
TEST(FileUtilsTests, ReadFile) {
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index c550eaf..1216f9ec 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -163,8 +163,12 @@
TEST_F(Idmap2BinaryTests, Scan) {
SKIP_TEST_IF_CANT_EXEC_IDMAP2;
+ const std::string overlay_static_no_name_apk_path =
+ GetTestDataPath() + "/overlay/overlay-no-name-static.apk";
const std::string overlay_static_1_apk_path = GetTestDataPath() + "/overlay/overlay-static-1.apk";
const std::string overlay_static_2_apk_path = GetTestDataPath() + "/overlay/overlay-static-2.apk";
+ const std::string idmap_static_no_name_path =
+ Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_no_name_apk_path);
const std::string idmap_static_1_path =
Idmap::CanonicalIdmapPathFor(GetTempDirPath(), overlay_static_1_apk_path);
const std::string idmap_static_2_path =
@@ -184,11 +188,18 @@
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
std::stringstream expected;
+ expected << idmap_static_no_name_path << std::endl;
expected << idmap_static_1_path << std::endl;
expected << idmap_static_2_path << std::endl;
ASSERT_EQ(result->stdout, expected.str());
std::stringstream error;
+ auto idmap_static_no_name_raw_string = utils::ReadFile(idmap_static_no_name_path);
+ auto idmap_static_no_name_raw_stream = std::istringstream(*idmap_static_no_name_raw_string);
+ auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream, error);
+ ASSERT_THAT(idmap_static_no_name, NotNull());
+ ASSERT_IDMAP(*idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path);
+
auto idmap_static_1_raw_string = utils::ReadFile(idmap_static_1_path);
auto idmap_static_1_raw_stream = std::istringstream(*idmap_static_1_raw_string);
auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream, error);
@@ -201,6 +212,7 @@
ASSERT_THAT(idmap_static_2, NotNull());
ASSERT_IDMAP(*idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path);
+ unlink(idmap_static_no_name_path.c_str());
unlink(idmap_static_2_path.c_str());
unlink(idmap_static_1_path.c_str());
@@ -218,6 +230,7 @@
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
ASSERT_EQ(result->stdout, expected.str());
+ unlink(idmap_static_no_name_path.c_str());
unlink(idmap_static_2_path.c_str());
unlink(idmap_static_1_path.c_str());
@@ -236,6 +249,7 @@
ASSERT_THAT(result, NotNull());
ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
ASSERT_EQ(result->stdout, expected.str());
+ unlink(idmap_static_no_name_path.c_str());
unlink(idmap_static_2_path.c_str());
unlink(idmap_static_1_path.c_str());
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index df28918..9e27ccd 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -224,7 +224,8 @@
ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
}
-TEST(IdmapTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
+// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -260,7 +261,8 @@
ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_system_vendor
}
-TEST(IdmapTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
+// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -290,17 +292,15 @@
ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
- ASSERT_EQ(types[0]->GetEntryCount(), 6U);
- ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
- ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
- ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/other
- ASSERT_EQ(types[0]->GetEntry(2), kNoEntry); // string/policy_product
- ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
- ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system
- ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
+ ASSERT_EQ(types[0]->GetEntryCount(), 3U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0004U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system_vendor
}
-TEST(IdmapTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
+// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
ASSERT_THAT(target_apk, NotNull());
@@ -340,6 +340,91 @@
ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
}
+// The resources of APKs that do not include an overlayable declaration should not restrict what
+// resources can be overlaid.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) {
+ const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
+ std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
+ ASSERT_THAT(target_apk, NotNull());
+
+ const std::string overlay_apk_path(GetTestDataPath() +
+ "/system-overlay-invalid/system-overlay-invalid.apk");
+ std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+ ASSERT_THAT(overlay_apk, NotNull());
+
+ std::stringstream error;
+ std::unique_ptr<const Idmap> idmap =
+ Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+ PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
+ ASSERT_THAT(idmap, NotNull());
+
+ const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
+ ASSERT_EQ(dataBlocks.size(), 1U);
+
+ const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
+
+ ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
+ ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
+
+ const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
+ ASSERT_EQ(types.size(), 1U);
+
+ ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
+ ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 6U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
+ ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor
+}
+
+// The resources of APKs that do not include an overlayable declaration should not restrict what
+// resources can be overlaid.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
+ const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
+ std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
+ ASSERT_THAT(target_apk, NotNull());
+
+ const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk");
+ std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+ ASSERT_THAT(overlay_apk, NotNull());
+
+ std::stringstream error;
+ std::unique_ptr<const Idmap> idmap =
+ Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+ PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
+ ASSERT_THAT(idmap, NotNull());
+
+ const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
+ ASSERT_EQ(dataBlocks.size(), 1U);
+
+ const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
+
+ ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
+ ASSERT_EQ(data->GetHeader()->GetTypeCount(), 2U);
+
+ const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
+ ASSERT_EQ(types.size(), 2U);
+
+ ASSERT_EQ(types[0]->GetTargetTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 1U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
+
+ ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
+ ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
+ ASSERT_EQ(types[1]->GetEntryCount(), 4U);
+ ASSERT_EQ(types[1]->GetEntryOffset(), 9U);
+ ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
+ ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
+ ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
+ ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
+}
+
TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
std::string target_apk_path(GetTestDataPath());
for (int i = 0; i < 32; i++) {
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml
index 9f89d31..a7767a6 100644
--- a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml
@@ -17,5 +17,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="test.overlay">
<overlay
- android:targetPackage="test.target" />
+ android:targetPackage="test.target"
+ android:targetName="TestResources"/>
</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml
new file mode 100644
index 0000000..bc6b733
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestNoName.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.overlay.no.name">
+ <overlay
+ android:targetPackage="test.target"/>
+</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml
new file mode 100644
index 0000000..ed327ce
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestNoNameStatic.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.overlay.no.name.static">
+ <overlay
+ android:targetPackage="test.target"
+ android:targetName="TestResources"
+ android:isStatic="true"
+ android:priority="1" />
+</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml
index 39336cc..1c4dae6 100644
--- a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic1.xml
@@ -18,6 +18,7 @@
package="test.overlay.static1">
<overlay
android:targetPackage="test.target"
+ android:targetName="TestResources"
android:isStatic="true"
android:priority="1" />
</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml
index e1cc175..70efc86 100644
--- a/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml
+++ b/cmds/idmap2/tests/data/overlay/AndroidManifestStatic2.xml
@@ -18,6 +18,7 @@
package="test.overlay.static2">
<overlay
android:targetPackage="test.target"
+ android:targetName="TestResources"
android:isStatic="true"
android:priority="2" />
</manifest>
diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build
index cba1086..e60da80 100644
--- a/cmds/idmap2/tests/data/overlay/build
+++ b/cmds/idmap2/tests/data/overlay/build
@@ -26,6 +26,20 @@
aapt2 link \
--no-resource-removal \
-I "$FRAMEWORK_RES_APK" \
+ --manifest AndroidManifestNoName.xml \
+ -o overlay-no-name.apk \
+ compiled.flata
+
+aapt2 link \
+ --no-resource-removal \
+ -I "$FRAMEWORK_RES_APK" \
+ --manifest AndroidManifestNoNameStatic.xml \
+ -o overlay-no-name-static.apk \
+ compiled.flata
+
+aapt2 link \
+ --no-resource-removal \
+ -I "$FRAMEWORK_RES_APK" \
--manifest AndroidManifestStatic1.xml \
-o overlay-static-1.apk \
compiled.flata
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
new file mode 100644
index 0000000..18ee43d
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name-static.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
new file mode 100644
index 0000000..7d23c09
--- /dev/null
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
index 9a0f487..642ab90 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-1.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
index 3fc31c7..2ec5602 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-static-2.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/overlay/overlay.apk b/cmds/idmap2/tests/data/overlay/overlay.apk
index b4cd7cf..5842da4 100644
--- a/cmds/idmap2/tests/data/overlay/overlay.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml
index 8af9064..5dacebd 100644
--- a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml
+++ b/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml
@@ -14,8 +14,9 @@
limitations under the License.
-->
<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="test.overlay.system">
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.overlay.system">
<overlay
- android:targetPackage="test.target" />
+ android:targetPackage="test.target"
+ android:targetName="TestResources"/>
</manifest>
diff --git a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
index 90f30eb..a0fba43 100644
--- a/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
+++ b/cmds/idmap2/tests/data/system-overlay/system-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/build b/cmds/idmap2/tests/data/target/build
index 8569c4f..137ddb5 100644
--- a/cmds/idmap2/tests/data/target/build
+++ b/cmds/idmap2/tests/data/target/build
@@ -15,3 +15,7 @@
aapt2 compile --dir res -o compiled.flata
aapt2 link --manifest AndroidManifest.xml -A assets -o target.apk compiled.flata
rm compiled.flata
+
+aapt2 compile res/values/values.xml -o .
+aapt2 link --manifest AndroidManifest.xml -A assets -o target_no_overlayable.apk values_values.arsc.flat
+rm values_values.arsc.flat
\ No newline at end of file
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
new file mode 100644
index 0000000..8676cbb
--- /dev/null
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 70ce9bc..bdd4706 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -633,6 +633,7 @@
overlayable_info.actor = actor;
overlayable_info.policy_flags = policy_header->policy_flags;
loaded_package->overlayable_infos_.push_back(std::make_pair(overlayable_info, ids));
+ loaded_package->defines_overlayable_ = true;
break;
}
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index be62f30..b5f4006 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -223,7 +223,7 @@
}
}
- // Retrieve the overlayable properties of the specified resource. If the resource is not
+ // Retrieves 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
@@ -235,6 +235,13 @@
return nullptr;
}
+ // Retrieves whether or not the package defines overlayable resources.
+ // TODO(123905379): Remove this when the enforcement of overlayable is turned on for all APK and
+ // not just those that defined overlayable resources.
+ bool DefinesOverlayable() const {
+ return defines_overlayable_;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
@@ -248,6 +255,7 @@
bool dynamic_ = false;
bool system_ = false;
bool overlay_ = false;
+ bool defines_overlayable_ = false;
ByteBucketArray<TypeSpecPtr> type_specs_;
ByteBucketArray<uint32_t> resource_ids_;