idmap2: add signature policy

Handles the new signature policy for overlayable resources.

Bug: 119402606

Test: idmap2_tests target

Change-Id: I7961e04a879c40c240ed9097bb510addb8b56680
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
index ea7274f..4a66715 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
@@ -24,6 +24,7 @@
   const int POLICY_SYSTEM_PARTITION = 0x00000002;
   const int POLICY_VENDOR_PARTITION = 0x00000004;
   const int POLICY_PRODUCT_PARTITION = 0x00000008;
+  const int POLICY_SIGNATURE = 0x00000010;
 
   @utf8InCpp String getIdmapPath(@utf8InCpp String overlayApkPath, int userId);
   boolean removeIdmap(@utf8InCpp String overlayApkPath, int userId);
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 99b5f0f..ec498ff 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -284,7 +284,7 @@
 
 bool CheckOverlayable(const LoadedPackage& target_package,
                       const utils::OverlayManifestInfo& overlay_info,
-                      const PolicyBitmask& fulfilled_polices, const ResourceId& resid) {
+                      const PolicyBitmask& fulfilled_policies, const ResourceId& resid) {
   const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(resid);
   if (overlayable_info == nullptr) {
     // If the resource does not have an overlayable definition, allow the resource to be overlaid.
@@ -299,7 +299,7 @@
   }
 
   // Enforce policy restrictions if the resource is declared as overlayable.
-  return (overlayable_info->policy_flags & fulfilled_polices) != 0;
+  return (overlayable_info->policy_flags & fulfilled_policies) != 0;
 }
 
 std::unique_ptr<const Idmap> Idmap::FromApkAssets(
diff --git a/cmds/idmap2/libidmap2/Policies.cpp b/cmds/idmap2/libidmap2/Policies.cpp
index 0f87ef0..6649288 100644
--- a/cmds/idmap2/libidmap2/Policies.cpp
+++ b/cmds/idmap2/libidmap2/Policies.cpp
@@ -35,6 +35,7 @@
     {"product", PolicyFlags::POLICY_PRODUCT_PARTITION},
     {"system", PolicyFlags::POLICY_SYSTEM_PARTITION},
     {"vendor", PolicyFlags::POLICY_VENDOR_PARTITION},
+    {"signature", PolicyFlags::POLICY_SIGNATURE},
 };
 }  // namespace
 
diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
index 0e0e25f..9a0412e 100644
--- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
+++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
@@ -129,28 +129,31 @@
   success = LoadedIdmap::Lookup(header, 0x0008, &entry);  // string/policy_system_vendor
   ASSERT_FALSE(success);
 
-  success = LoadedIdmap::Lookup(header, 0x0009, &entry);  // string/str1
+  success = LoadedIdmap::Lookup(header, 0x0009, &entry);  // string/policy_signature
+  ASSERT_FALSE(success);
+
+  success = LoadedIdmap::Lookup(header, 0x000a, &entry);  // string/str1
   ASSERT_TRUE(success);
   ASSERT_EQ(entry, 0x0000);
 
-  success = LoadedIdmap::Lookup(header, 0x000a, &entry);  // string/str2
+  success = LoadedIdmap::Lookup(header, 0x000b, &entry);  // string/str2
   ASSERT_FALSE(success);
 
-  success = LoadedIdmap::Lookup(header, 0x000b, &entry);  // string/str3
+  success = LoadedIdmap::Lookup(header, 0x000c, &entry);  // string/str3
   ASSERT_TRUE(success);
   ASSERT_EQ(entry, 0x0001);
 
-  success = LoadedIdmap::Lookup(header, 0x000c, &entry);  // string/str4
+  success = LoadedIdmap::Lookup(header, 0x000d, &entry);  // string/str4
   ASSERT_TRUE(success);
   ASSERT_EQ(entry, 0x0002);
 
-  success = LoadedIdmap::Lookup(header, 0x000d, &entry);  // string/x
+  success = LoadedIdmap::Lookup(header, 0x000e, &entry);  // string/x
   ASSERT_FALSE(success);
 
-  success = LoadedIdmap::Lookup(header, 0x000e, &entry);  // string/y
+  success = LoadedIdmap::Lookup(header, 0x000f, &entry);  // string/y
   ASSERT_FALSE(success);
 
-  success = LoadedIdmap::Lookup(header, 0x000f, &entry);  // string/z
+  success = LoadedIdmap::Lookup(header, 0x0010, &entry);  // string/z
   ASSERT_FALSE(success);
 }
 
diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp
index 8514e12..2e85eb6 100644
--- a/cmds/idmap2/tests/FileUtilsTests.cpp
+++ b/cmds/idmap2/tests/FileUtilsTests.cpp
@@ -39,12 +39,13 @@
                             [](unsigned char type ATTRIBUTE_UNUSED,
                                const std::string& path ATTRIBUTE_UNUSED) -> bool { return true; });
   ASSERT_THAT(v, NotNull());
-  ASSERT_EQ(v->size(), 6U);
+  ASSERT_EQ(v->size(), 7U);
   ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>({
                                                              root + "/.",
                                                              root + "/..",
                                                              root + "/overlay",
                                                              root + "/target",
+                                                             root + "/signature-overlay",
                                                              root + "/system-overlay",
                                                              root + "/system-overlay-invalid",
                                                          }));
@@ -56,15 +57,22 @@
     return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0;
   });
   ASSERT_THAT(v, NotNull());
-  ASSERT_EQ(v->size(), 9U);
+  ASSERT_EQ(v->size(), 10U);
   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"}));
+          {
+              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 + "/signature-overlay/signature-overlay.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 1216f9ec..a6a2ada 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -132,9 +132,9 @@
   ASSERT_THAT(result, NotNull());
   ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
   ASSERT_NE(result->stdout.find("0x7f010000 -> 0x7f010000 integer/int1"), std::string::npos);
-  ASSERT_NE(result->stdout.find("0x7f020009 -> 0x7f020000 string/str1"), std::string::npos);
-  ASSERT_NE(result->stdout.find("0x7f02000b -> 0x7f020001 string/str3"), std::string::npos);
-  ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020002 string/str4"), std::string::npos);
+  ASSERT_NE(result->stdout.find("0x7f02000a -> 0x7f020000 string/str1"), std::string::npos);
+  ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020001 string/str3"), std::string::npos);
+  ASSERT_NE(result->stdout.find("0x7f02000d -> 0x7f020002 string/str4"), std::string::npos);
   ASSERT_EQ(result->stdout.find("00000210:     007f  target package id"), std::string::npos);
 
   // clang-format off
@@ -286,7 +286,7 @@
                           "lookup",
                           "--idmap-path", GetIdmapPath(),
                           "--config", "",
-                          "--resid", "0x7f020009"});  // string/str1
+                          "--resid", "0x7f02000a"});  // string/str1
   // clang-format on
   ASSERT_THAT(result, NotNull());
   ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr;
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index b40521f..53ec03b 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -191,8 +191,8 @@
   ASSERT_THAT(idmap->GetHeader(), NotNull());
   ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
   ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
-  ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xdd53ca29);
-  ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xa71ccd77);
+  ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xd513ca1b);
+  ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x8635c2ed);
   ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
@@ -217,7 +217,7 @@
   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]->GetEntryOffset(), 10U);
   ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
   ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
   ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
@@ -254,11 +254,76 @@
 
   ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
   ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
-  ASSERT_EQ(types[0]->GetEntryCount(), 3U);
+  ASSERT_EQ(types[0]->GetEntryCount(), 4U);
   ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
   ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);  // string/policy_public
-  ASSERT_EQ(types[0]->GetEntry(1), 0x0001U);  // string/policy_system
-  ASSERT_EQ(types[0]->GetEntry(2), 0x0002U);  // string/policy_system_vendor
+  ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
+  ASSERT_EQ(types[0]->GetEntry(2), 0x0001U);  // string/policy_system
+  ASSERT_EQ(types[0]->GetEntry(3), 0x0002U);  // string/policy_system_vendor
+}
+
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
+  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());
+
+  const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk");
+  std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+  ASSERT_THAT(overlay_apk, NotNull());
+
+  uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE;
+
+  std::stringstream error;
+  std::unique_ptr<const Idmap> idmap =
+      Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+                           policy_flags, /* 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(), 1U);
+  ASSERT_EQ(types[0]->GetEntryOffset(), 7U);
+  ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
+}
+
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) {
+  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());
+
+  const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk");
+  std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+  ASSERT_THAT(overlay_apk, NotNull());
+
+  uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC;
+
+  std::stringstream error;
+  std::unique_ptr<const Idmap> idmap =
+      Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
+                           policy_flags, /* 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(), 0U);
+
+  const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
+  ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing
 }
 
 // Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
@@ -292,11 +357,12 @@
 
   ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
   ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
-  ASSERT_EQ(types[0]->GetEntryCount(), 3U);
+  ASSERT_EQ(types[0]->GetEntryCount(), 4U);
   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
+  ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
+  ASSERT_EQ(types[0]->GetEntry(2), 0x0005U);  // string/policy_system
+  ASSERT_EQ(types[0]->GetEntry(3), 0x0006U);  // string/policy_system_vendor
 }
 
 // Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
@@ -330,14 +396,15 @@
 
   ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
   ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
-  ASSERT_EQ(types[0]->GetEntryCount(), 6U);
+  ASSERT_EQ(types[0]->GetEntryCount(), 7U);
   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
+  ASSERT_EQ(types[0]->GetEntry(3), 0x0003U);  // string/policy_signature
+  ASSERT_EQ(types[0]->GetEntry(4), 0x0004U);  // string/policy_public
+  ASSERT_EQ(types[0]->GetEntry(5), 0x0005U);  // string/policy_system
+  ASSERT_EQ(types[0]->GetEntry(6), 0x0006U);  // string/policy_system_vendor
 }
 
 // The resources of APKs that do not include an overlayable declaration should not restrict what
@@ -371,14 +438,15 @@
 
   ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
   ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
-  ASSERT_EQ(types[0]->GetEntryCount(), 6U);
+  ASSERT_EQ(types[0]->GetEntryCount(), 7U);
   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
+  ASSERT_EQ(types[0]->GetEntry(4), 0x0004U);  // string/string/policy_signature
+  ASSERT_EQ(types[0]->GetEntry(5), 0x0005U);  // string/policy_system
+  ASSERT_EQ(types[0]->GetEntry(6), 0x0006U);  // string/policy_system_vendor
 }
 
 // The resources of APKs that do not include an overlayable declaration should not restrict what
@@ -418,7 +486,7 @@
   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]->GetEntryOffset(), 10U);
   ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
   ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
   ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index a5588c3..7ec13ed 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -52,8 +52,8 @@
 
   ASSERT_NE(stream.str().find("00000000: 504d4449  magic\n"), std::string::npos);
   ASSERT_NE(stream.str().find("00000004: 00000001  version\n"), std::string::npos);
-  ASSERT_NE(stream.str().find("00000008: dd53ca29  target crc\n"), std::string::npos);
-  ASSERT_NE(stream.str().find("0000000c: a71ccd77  overlay crc\n"), std::string::npos);
+  ASSERT_NE(stream.str().find("00000008: d513ca1b  target crc\n"), std::string::npos);
+  ASSERT_NE(stream.str().find("0000000c: 8635c2ed  overlay crc\n"), std::string::npos);
   ASSERT_NE(stream.str().find("0000021c: 00000000  0x7f010000 -> 0x7f010000 integer/int1\n"),
             std::string::npos);
 }
diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build
old mode 100644
new mode 100755
index e60da80..e879f44
--- a/cmds/idmap2/tests/data/overlay/build
+++ b/cmds/idmap2/tests/data/overlay/build
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FRAMEWORK_RES_APK="$(gettop)/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk"
+FRAMEWORK_RES_APK="${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk"
 
 aapt2 compile --dir res -o compiled.flata
 
diff --git a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml
new file mode 100644
index 0000000..5dacebd
--- /dev/null
+++ b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?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.system">
+    <overlay
+        android:targetPackage="test.target"
+        android:targetName="TestResources"/>
+</manifest>
diff --git a/cmds/idmap2/tests/data/signature-overlay/build b/cmds/idmap2/tests/data/signature-overlay/build
new file mode 100755
index 0000000..fdd8301
--- /dev/null
+++ b/cmds/idmap2/tests/data/signature-overlay/build
@@ -0,0 +1,26 @@
+# 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.
+
+FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar
+
+aapt2 compile --dir res -o compiled.flata
+
+aapt2 link \
+    --no-resource-removal \
+    -I "$FRAMEWORK_RES_APK" \
+    --manifest AndroidManifest.xml \
+    -o signature-overlay.apk \
+    compiled.flata
+
+rm compiled.flata
diff --git a/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml b/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml
new file mode 100644
index 0000000..59e7d8e
--- /dev/null
+++ b/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+    <!-- This overlay will fulfill the policy "signature". This allows it overlay the
+     following resources. -->
+    <string name="policy_signature">policy_signature</string>
+</resources>
diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
new file mode 100644
index 0000000..b2c490d
--- /dev/null
+++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/build b/cmds/idmap2/tests/data/system-overlay-invalid/build
old mode 100644
new mode 100755
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
index af1bea1..0270400 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
@@ -22,6 +22,7 @@
 
     <!-- Requests to overlay a resource that belongs to a policy the overlay does not fulfill. -->
     <string name="policy_product">policy_product</string>
+    <string name="policy_signature">policy_signature</string>
 
     <!-- Requests to overlay a resource that is not declared as overlayable. -->
     <string name="not_overlayable">not_overlayable</string>
diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
index 710ed90..9448939 100644
--- a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
+++ b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/system-overlay/build b/cmds/idmap2/tests/data/system-overlay/build
old mode 100644
new mode 100755
diff --git a/cmds/idmap2/tests/data/target/build b/cmds/idmap2/tests/data/target/build
old mode 100644
new mode 100755
index 137ddb5..e6df742
--- a/cmds/idmap2/tests/data/target/build
+++ b/cmds/idmap2/tests/data/target/build
@@ -17,5 +17,5 @@
 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
+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/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
index 02d2563..0bf83fa 100644
--- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml
+++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
@@ -15,20 +15,12 @@
 -->
 <resources>
 <overlayable name="TestResources">
-    <!-- Publicly overlayable resources -->
-    <item type="string" name="a" />
-    <item type="string" name="b" />
-    <item type="string" name="c" />
-    <item type="string" name="str1" />
-    <item type="string" name="str2" />
-    <item type="string" name="str3" />
-    <item type="string" name="str4" />
-    <item type="string" name="x" />
-    <item type="string" name="y" />
-    <item type="string" name="z" />
-    <item type="integer" name="int1" />
+    <!-- Resources with signature restrictions -->
+    <policy type="signature">
+        <item type="string" name="policy_signature" />
+    </policy>
 
-    <!-- Resources with partition restrictins -->
+    <!-- Resources with partition restrictions -->
     <policy type="system">
         <item type="string" name="policy_system" />
     </policy>
@@ -41,12 +33,26 @@
         <item type="string" name="policy_product" />
     </policy>
 
+    <!-- Resources publicly overlayable -->
     <policy type="public">
         <item type="string" name="policy_public" />
+        <item type="string" name="a" />
+        <item type="string" name="b" />
+        <item type="string" name="c" />
+        <item type="string" name="str1" />
+        <item type="string" name="str2" />
+        <item type="string" name="str3" />
+        <item type="string" name="str4" />
+        <item type="string" name="x" />
+        <item type="string" name="y" />
+        <item type="string" name="z" />
+        <item type="integer" name="int1" />
     </policy>
 </overlayable>
 
 <overlayable name="OtherResources">
-    <item type="string" name="other" />
+    <policy type="public">
+        <item type="string" name="other" />
+    </policy>
 </overlayable>
 </resources>
\ No newline at end of file
diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml
index 0d337f3..edd53f4 100644
--- a/cmds/idmap2/tests/data/target/res/values/values.xml
+++ b/cmds/idmap2/tests/data/target/res/values/values.xml
@@ -33,6 +33,7 @@
     <string name="policy_system_vendor">policy_system_vendor</string>
     <string name="policy_product">policy_product</string>
     <string name="policy_public">policy_public</string>
+    <string name="policy_signature">policy_signature</string>
 
     <item type="string" name="other" />
 </resources>
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
index 8676cbb..908b54a 100644
--- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk
index ecbe875..da3c1ae 100644
--- a/cmds/idmap2/tests/data/target/target.apk
+++ b/cmds/idmap2/tests/data/target/target.apk
Binary files differ