summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl1
-rw-r--r--cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h6
-rw-r--r--cmds/idmap2/tests/IdmapTests.cpp24
-rw-r--r--cmds/idmap2/tests/PoliciesTests.cpp16
-rw-r--r--cmds/idmap2/tests/R.h47
-rw-r--r--cmds/idmap2/tests/ResourceMappingTests.cpp10
-rw-r--r--cmds/idmap2/tests/TestConstants.h4
-rw-r--r--cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml1
-rw-r--r--cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apkbin1779 -> 1827 bytes
-rw-r--r--cmds/idmap2/tests/data/target/res/values/overlayable.xml6
-rw-r--r--cmds/idmap2/tests/data/target/res/values/values.xml1
-rw-r--r--cmds/idmap2/tests/data/target/target-no-overlayable.apkbin2749 -> 2311 bytes
-rw-r--r--cmds/idmap2/tests/data/target/target.apkbin5017 -> 5097 bytes
-rw-r--r--core/java/android/content/om/OverlayInfo.java4
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h9
-rw-r--r--services/core/java/com/android/server/om/IdmapManager.java39
-rw-r--r--services/core/java/com/android/server/om/OverlayActorEnforcer.java72
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java18
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerServiceImpl.java8
-rw-r--r--services/core/java/com/android/server/om/OverlayableInfoCallback.java85
-rw-r--r--services/core/java/com/android/server/om/PackageManagerHelper.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt9
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java37
-rw-r--r--tools/aapt2/ResourceParser_test.cpp11
-rw-r--r--tools/aapt2/Resources.proto1
-rw-r--r--tools/aapt2/format/binary/TableFlattener_test.cpp4
-rw-r--r--tools/aapt2/format/proto/ProtoDeserialize.cpp3
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize.cpp3
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize_test.cpp15
30 files changed, 343 insertions, 141 deletions
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
index 85b5eff46efa..02b27a8800b6 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/OverlayablePolicy.aidl
@@ -28,4 +28,5 @@ interface OverlayablePolicy {
const int SIGNATURE = 0x00000010;
const int ODM_PARTITION = 0x00000020;
const int OEM_PARTITION = 0x00000040;
+ const int ACTOR_SIGNATURE = 0x00000080;
}
diff --git a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
index 9f9b836e31d5..4973b7638d10 100644
--- a/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
+++ b/cmds/idmap2/libidmap2_policies/include/idmap2/Policies.h
@@ -29,6 +29,7 @@ using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
namespace android::idmap2::policy {
+constexpr const char* kPolicyActor = "actor";
constexpr const char* kPolicyOdm = "odm";
constexpr const char* kPolicyOem = "oem";
constexpr const char* kPolicyProduct = "product";
@@ -37,8 +38,9 @@ constexpr const char* kPolicySignature = "signature";
constexpr const char* kPolicySystem = "system";
constexpr const char* kPolicyVendor = "vendor";
-inline static const std::array<std::pair<StringPiece, PolicyFlags>, 7> kPolicyStringToFlag = {
- std::pair{kPolicyOdm, PolicyFlags::ODM_PARTITION},
+inline static const std::array<std::pair<StringPiece, PolicyFlags>, 8> kPolicyStringToFlag = {
+ std::pair{kPolicyActor, PolicyFlags::ACTOR_SIGNATURE},
+ {kPolicyOdm, PolicyFlags::ODM_PARTITION},
{kPolicyOem, PolicyFlags::OEM_PARTITION},
{kPolicyProduct, PolicyFlags::PRODUCT_PARTITION},
{kPolicyPublic, PolicyFlags::PUBLIC},
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 76c6eaf75adc..87da36c01192 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -279,17 +279,25 @@ TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) {
const auto& target_entries = data->GetTargetEntries();
ASSERT_EQ(target_entries.size(), 4U);
- ASSERT_TARGET_ENTRY(target_entries[0], 0x7f010000, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00010000);
- ASSERT_TARGET_ENTRY(target_entries[1], 0x7f02000c, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020000);
- ASSERT_TARGET_ENTRY(target_entries[2], 0x7f02000e, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020001);
- ASSERT_TARGET_ENTRY(target_entries[3], 0x7f02000f, Res_value::TYPE_DYNAMIC_REFERENCE, 0x00020002);
+ ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1,
+ Res_value::TYPE_DYNAMIC_REFERENCE, R::overlay_shared::integer::int1);
+ ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, Res_value::TYPE_DYNAMIC_REFERENCE,
+ R::overlay_shared::string::str1);
+ ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, Res_value::TYPE_DYNAMIC_REFERENCE,
+ R::overlay_shared::string::str3);
+ ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, Res_value::TYPE_DYNAMIC_REFERENCE,
+ R::overlay_shared::string::str4);
const auto& overlay_entries = data->GetOverlayEntries();
ASSERT_EQ(target_entries.size(), 4U);
- ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x00010000, 0x7f010000);
- ASSERT_OVERLAY_ENTRY(overlay_entries[1], 0x00020000, 0x7f02000c);
- ASSERT_OVERLAY_ENTRY(overlay_entries[2], 0x00020001, 0x7f02000e);
- ASSERT_OVERLAY_ENTRY(overlay_entries[3], 0x00020002, 0x7f02000f);
+ ASSERT_OVERLAY_ENTRY(overlay_entries[0], R::overlay_shared::integer::int1,
+ R::target::integer::int1);
+ ASSERT_OVERLAY_ENTRY(overlay_entries[1], R::overlay_shared::string::str1,
+ R::target::string::str1);
+ ASSERT_OVERLAY_ENTRY(overlay_entries[2], R::overlay_shared::string::str3,
+ R::target::string::str3);
+ ASSERT_OVERLAY_ENTRY(overlay_entries[3], R::overlay_shared::string::str4,
+ R::target::string::str4);
}
TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) {
diff --git a/cmds/idmap2/tests/PoliciesTests.cpp b/cmds/idmap2/tests/PoliciesTests.cpp
index 4b395c7912d1..1b2775939886 100644
--- a/cmds/idmap2/tests/PoliciesTests.cpp
+++ b/cmds/idmap2/tests/PoliciesTests.cpp
@@ -67,6 +67,14 @@ TEST(PoliciesTests, PoliciesToBitmaskResults) {
const auto bitmask10 = PoliciesToBitmaskResult({"system "});
ASSERT_FALSE(bitmask10);
+
+ const auto bitmask11 = PoliciesToBitmaskResult({"signature"});
+ ASSERT_TRUE(bitmask11);
+ ASSERT_EQ(*bitmask11, PolicyFlags::SIGNATURE);
+
+ const auto bitmask12 = PoliciesToBitmaskResult({"actor"});
+ ASSERT_TRUE(bitmask12);
+ ASSERT_EQ(*bitmask12, PolicyFlags::ACTOR_SIGNATURE);
}
TEST(PoliciesTests, BitmaskToPolicies) {
@@ -91,6 +99,14 @@ TEST(PoliciesTests, BitmaskToPolicies) {
ASSERT_EQ(policies3[3], "public");
ASSERT_EQ(policies3[4], "system");
ASSERT_EQ(policies3[5], "vendor");
+
+ const auto policies4 = BitmaskToPolicies(PolicyFlags::SIGNATURE);
+ ASSERT_EQ(1, policies4.size());
+ ASSERT_EQ(policies4[0], "signature");
+
+ const auto policies5 = BitmaskToPolicies(PolicyFlags::ACTOR_SIGNATURE);
+ ASSERT_EQ(1, policies5.size());
+ ASSERT_EQ(policies5[0], "actor");
}
} // namespace android::idmap2
diff --git a/cmds/idmap2/tests/R.h b/cmds/idmap2/tests/R.h
index b2a589144c77..aed263a49aa3 100644
--- a/cmds/idmap2/tests/R.h
+++ b/cmds/idmap2/tests/R.h
@@ -40,16 +40,17 @@ namespace R::target {
namespace string {
constexpr ResourceId not_overlayable = 0x7f020003;
constexpr ResourceId other = 0x7f020004;
- constexpr ResourceId policy_odm = 0x7f020005;
- constexpr ResourceId policy_oem = 0x7f020006;
- constexpr ResourceId policy_product = 0x7f020007;
- constexpr ResourceId policy_public = 0x7f020008;
- constexpr ResourceId policy_signature = 0x7f020009;
- constexpr ResourceId policy_system = 0x7f02000a;
- constexpr ResourceId policy_system_vendor = 0x7f02000b;
- constexpr ResourceId str1 = 0x7f02000c;
- constexpr ResourceId str3 = 0x7f02000e;
- constexpr ResourceId str4 = 0x7f02000f;
+ constexpr ResourceId policy_actor = 0x7f020005;
+ constexpr ResourceId policy_odm = 0x7f020006;
+ constexpr ResourceId policy_oem = 0x7f020007;
+ constexpr ResourceId policy_product = 0x7f020008;
+ constexpr ResourceId policy_public = 0x7f020009;
+ constexpr ResourceId policy_signature = 0x7f02000a;
+ constexpr ResourceId policy_system = 0x7f02000b;
+ constexpr ResourceId policy_system_vendor = 0x7f02000c;
+ constexpr ResourceId str1 = 0x7f02000d;
+ constexpr ResourceId str3 = 0x7f02000f;
+ constexpr ResourceId str4 = 0x7f020010;
namespace literal {
inline const std::string str1 = hexify(R::target::string::str1);
@@ -70,6 +71,17 @@ namespace R::overlay {
}
}
+namespace R::overlay_shared {
+ namespace integer {
+ constexpr ResourceId int1 = 0x00010000;
+ }
+ namespace string {
+ constexpr ResourceId str1 = 0x00020000;
+ constexpr ResourceId str3 = 0x00020001;
+ constexpr ResourceId str4 = 0x00020002;
+ }
+}
+
namespace R::system_overlay::string {
constexpr ResourceId policy_public = 0x7f010000;
constexpr ResourceId policy_system = 0x7f010001;
@@ -79,13 +91,14 @@ namespace R::system_overlay::string {
namespace R::system_overlay_invalid::string {
constexpr ResourceId not_overlayable = 0x7f010000;
constexpr ResourceId other = 0x7f010001;
- constexpr ResourceId policy_odm = 0x7f010002;
- constexpr ResourceId policy_oem = 0x7f010003;
- constexpr ResourceId policy_product = 0x7f010004;
- constexpr ResourceId policy_public = 0x7f010005;
- constexpr ResourceId policy_signature = 0x7f010006;
- constexpr ResourceId policy_system = 0x7f010007;
- constexpr ResourceId policy_system_vendor = 0x7f010008;
+ constexpr ResourceId policy_actor = 0x7f010002;
+ constexpr ResourceId policy_odm = 0x7f010003;
+ constexpr ResourceId policy_oem = 0x7f010004;
+ constexpr ResourceId policy_product = 0x7f010005;
+ constexpr ResourceId policy_public = 0x7f010006;
+ constexpr ResourceId policy_signature = 0x7f010007;
+ constexpr ResourceId policy_system = 0x7f010008;
+ constexpr ResourceId policy_system_vendor = 0x7f010009;
};
// clang-format on
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 8d0e6609ac40..de039f440e33 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -237,12 +237,15 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnore
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(res.GetTargetToOverlayMap().size(), 9U);
+ ASSERT_EQ(res.GetTargetToOverlayMap().size(), 10U);
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::other, false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor, Res_value::TYPE_REFERENCE,
+ R::system_overlay_invalid::string::policy_actor,
+ false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_odm, false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE,
@@ -306,12 +309,15 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
ASSERT_TRUE(resources) << resources.GetErrorMessage();
auto& res = *resources;
- ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 9U);
+ ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 10U);
ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::not_overlayable,
false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::other, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::other, false /* rewrite */));
+ ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor, Res_value::TYPE_REFERENCE,
+ R::system_overlay_invalid::string::policy_actor,
+ false /* rewrite */));
ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, Res_value::TYPE_REFERENCE,
R::system_overlay_invalid::string::policy_odm,
false /* rewrite */));
diff --git a/cmds/idmap2/tests/TestConstants.h b/cmds/idmap2/tests/TestConstants.h
index c874dc93ce79..6bc924e5ac3c 100644
--- a/cmds/idmap2/tests/TestConstants.h
+++ b/cmds/idmap2/tests/TestConstants.h
@@ -19,8 +19,8 @@
namespace android::idmap2::TestConstants {
-constexpr const auto TARGET_CRC = 0x76a20829;
-constexpr const auto TARGET_CRC_STRING = "76a20829";
+constexpr const auto TARGET_CRC = 0x41c60c8c;
+constexpr const auto TARGET_CRC_STRING = "41c60c8c";
constexpr const auto OVERLAY_CRC = 0xc054fb26;
constexpr const auto OVERLAY_CRC_STRING = "c054fb26";
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 9ebfae41e4c5..7119d8283061 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
@@ -25,6 +25,7 @@
<string name="policy_signature">policy_signature</string>
<string name="policy_odm">policy_odm</string>
<string name="policy_oem">policy_oem</string>
+ <string name="policy_actor">policy_actor</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 1456e749e796..bd990983693c 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/target/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
index 8389f5635e15..ad4cd4882632 100644
--- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml
+++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
@@ -41,6 +41,10 @@
<item type="string" name="policy_oem" />
</policy>
+ <policy type="actor">
+ <item type="string" name="policy_actor" />
+ </policy>
+
<!-- Resources publicly overlayable -->
<policy type="public">
<item type="string" name="policy_public" />
@@ -63,4 +67,4 @@
<item type="string" name="other" />
</policy>
</overlayable>
-</resources> \ No newline at end of file
+</resources>
diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml
index a892c98f0fbb..5230e25e626b 100644
--- a/cmds/idmap2/tests/data/target/res/values/values.xml
+++ b/cmds/idmap2/tests/data/target/res/values/values.xml
@@ -36,6 +36,7 @@
<string name="policy_signature">policy_signature</string>
<string name="policy_system">policy_system</string>
<string name="policy_system_vendor">policy_system_vendor</string>
+ <string name="policy_actor">policy_actor</string>
<string name="other">other</string>
</resources>
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
index 2eb7c477c3b4..58504a74a83a 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 251cf46f969d..c80e5eb65ff2 100644
--- a/cmds/idmap2/tests/data/target/target.apk
+++ b/cmds/idmap2/tests/data/target/target.apk
Binary files differ
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index 55a6cab2f2d5..62815ddcfc19 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -138,6 +138,7 @@ public final class OverlayInfo implements Parcelable {
*
* @hide
*/
+ @NonNull
public final String packageName;
/**
@@ -145,6 +146,7 @@ public final class OverlayInfo implements Parcelable {
*
* @hide
*/
+ @NonNull
public final String targetPackageName;
/**
@@ -165,6 +167,7 @@ public final class OverlayInfo implements Parcelable {
* Full path to the base APK for this overlay package
* @hide
*/
+ @NonNull
public final String baseCodePath;
/**
@@ -292,6 +295,7 @@ public final class OverlayInfo implements Parcelable {
return targetOverlayableName;
}
+ @SuppressWarnings("ConstantConditions")
private void ensureValidState() {
if (packageName == null) {
throw new IllegalArgumentException("packageName must not be null");
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index d15a3a27cbb1..2bfc7fc38d1c 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1682,7 +1682,6 @@ struct ResTable_overlayable_policy_header
* Flags for a bitmask for all possible overlayable policy options.
*
* Any changes to this set should also update aidl/android/os/OverlayablePolicy.aidl
- * and proto/OverlayablePolicy.proto.
*/
enum PolicyFlags : uint32_t {
// Base
@@ -1703,8 +1702,8 @@ struct ResTable_overlayable_policy_header
// partition before an upgrade to overlay these resources.
PRODUCT_PARTITION = 0x00000008,
- // The overlay must be signed with the same signature as the actor of the target resource,
- // which can be separate or the same as the target package with the resource.
+ // The overlay must be signed with the same signature as the package containing the target
+ // resource
SIGNATURE = 0x00000010,
// The overlay must reside of the odm partition or must have existed on the odm
@@ -1714,6 +1713,10 @@ struct ResTable_overlayable_policy_header
// The overlay must reside of the oem partition or must have existed on the oem
// partition before an upgrade to overlay these resources.
OEM_PARTITION = 0x00000040,
+
+ // The overlay must be signed with the same signature as the actor declared for the target
+ // resource
+ ACTOR_SIGNATURE = 0x00000080,
};
using PolicyBitmask = uint32_t;
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 48a1afd2be59..7c9be2dfacd6 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -21,6 +21,7 @@ import static com.android.server.om.OverlayManagerService.TAG;
import android.annotation.NonNull;
import android.content.om.OverlayInfo;
+import android.content.om.OverlayableInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Build.VERSION_CODES;
@@ -29,9 +30,8 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Slog;
-import com.android.server.om.OverlayManagerServiceImpl.PackageManagerHelper;
-
import java.io.File;
+import java.io.IOException;
/**
* Handle the creation and deletion of idmap files.
@@ -55,11 +55,11 @@ class IdmapManager {
VENDOR_IS_Q_OR_LATER = isQOrLater;
}
- private final PackageManagerHelper mPackageManager;
+ private final OverlayableInfoCallback mOverlayableCallback;
private final IdmapDaemon mIdmapDaemon;
- IdmapManager(final PackageManagerHelper packageManager) {
- mPackageManager = packageManager;
+ IdmapManager(final OverlayableInfoCallback verifyCallback) {
+ mOverlayableCallback = verifyCallback;
mIdmapDaemon = IdmapDaemon.getInstance();
}
@@ -151,11 +151,16 @@ class IdmapManager {
int fulfilledPolicies = OverlayablePolicy.PUBLIC;
// Overlay matches target signature
- if (mPackageManager.signaturesMatching(targetPackage.packageName,
+ if (mOverlayableCallback.signaturesMatching(targetPackage.packageName,
overlayPackage.packageName, userId)) {
fulfilledPolicies |= OverlayablePolicy.SIGNATURE;
}
+ // Overlay matches actor signature
+ if (matchesActorSignature(targetPackage, overlayPackage, userId)) {
+ fulfilledPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
+ }
+
// Vendor partition (/vendor)
if (ai.isVendor()) {
return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION;
@@ -184,4 +189,26 @@ class IdmapManager {
return fulfilledPolicies;
}
+
+ private boolean matchesActorSignature(@NonNull PackageInfo targetPackage,
+ @NonNull PackageInfo overlayPackage, int userId) {
+ String targetOverlayableName = overlayPackage.targetOverlayableName;
+ if (targetOverlayableName != null) {
+ try {
+ OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
+ targetPackage.packageName, targetOverlayableName, userId);
+ if (overlayableInfo != null) {
+ String actorPackageName = OverlayActorEnforcer.getPackageNameForActor(
+ overlayableInfo.actor, mOverlayableCallback.getNamedActors()).first;
+ if (mOverlayableCallback.signaturesMatching(actorPackageName,
+ overlayPackage.packageName, userId)) {
+ return true;
+ }
+ }
+ } catch (IOException ignored) {
+ }
+ }
+
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
index 4c85603a719c..40efb7cd96d7 100644
--- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java
+++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java
@@ -17,7 +17,6 @@
package com.android.server.om;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.om.OverlayInfo;
import android.content.om.OverlayableInfo;
import android.content.pm.ApplicationInfo;
@@ -46,7 +45,7 @@ public class OverlayActorEnforcer {
// By default, the reason is not logged to prevent leaks of why it failed
private static final boolean DEBUG_REASON = false;
- private final VerifyCallback mVerifyCallback;
+ private final OverlayableInfoCallback mOverlayableCallback;
/**
* @return nullable actor result with {@link ActorState} failure status
@@ -80,8 +79,8 @@ public class OverlayActorEnforcer {
return Pair.create(packageName, ActorState.ALLOWED);
}
- public OverlayActorEnforcer(@NonNull VerifyCallback verifyCallback) {
- mVerifyCallback = verifyCallback;
+ public OverlayActorEnforcer(@NonNull OverlayableInfoCallback overlayableCallback) {
+ mOverlayableCallback = overlayableCallback;
}
void enforceActor(@NonNull OverlayInfo overlayInfo, @NonNull String methodName,
@@ -117,7 +116,7 @@ public class OverlayActorEnforcer {
return ActorState.ALLOWED;
}
- String[] callingPackageNames = mVerifyCallback.getPackagesForUid(callingUid);
+ String[] callingPackageNames = mOverlayableCallback.getPackagesForUid(callingUid);
if (ArrayUtils.isEmpty(callingPackageNames)) {
return ActorState.NO_PACKAGES_FOR_UID;
}
@@ -132,12 +131,12 @@ public class OverlayActorEnforcer {
if (TextUtils.isEmpty(targetOverlayableName)) {
try {
- if (mVerifyCallback.doesTargetDefineOverlayable(targetPackageName, userId)) {
+ if (mOverlayableCallback.doesTargetDefineOverlayable(targetPackageName, userId)) {
return ActorState.MISSING_TARGET_OVERLAYABLE_NAME;
} else {
// If there's no overlayable defined, fallback to the legacy permission check
try {
- mVerifyCallback.enforcePermission(
+ mOverlayableCallback.enforcePermission(
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
// If the previous method didn't throw, check passed
@@ -153,7 +152,7 @@ public class OverlayActorEnforcer {
OverlayableInfo targetOverlayable;
try {
- targetOverlayable = mVerifyCallback.getOverlayableForTarget(targetPackageName,
+ targetOverlayable = mOverlayableCallback.getOverlayableForTarget(targetPackageName,
targetOverlayableName, userId);
} catch (IOException e) {
return ActorState.UNABLE_TO_GET_TARGET;
@@ -167,7 +166,7 @@ public class OverlayActorEnforcer {
if (TextUtils.isEmpty(actor)) {
// If there's no actor defined, fallback to the legacy permission check
try {
- mVerifyCallback.enforcePermission(
+ mOverlayableCallback.enforcePermission(
android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, methodName);
// If the previous method didn't throw, check passed
@@ -177,7 +176,7 @@ public class OverlayActorEnforcer {
}
}
- Map<String, Map<String, String>> namedActors = mVerifyCallback.getNamedActors();
+ Map<String, Map<String, String>> namedActors = mOverlayableCallback.getNamedActors();
Pair<String, ActorState> actorUriPair = getPackageNameForActor(actor, namedActors);
ActorState actorUriState = actorUriPair.second;
if (actorUriState != ActorState.ALLOWED) {
@@ -185,7 +184,7 @@ public class OverlayActorEnforcer {
}
String packageName = actorUriPair.first;
- PackageInfo packageInfo = mVerifyCallback.getPackageInfo(packageName, userId);
+ PackageInfo packageInfo = mOverlayableCallback.getPackageInfo(packageName, userId);
if (packageInfo == null) {
return ActorState.MISSING_APP_INFO;
}
@@ -211,7 +210,7 @@ public class OverlayActorEnforcer {
* For easier logging/debugging, a set of all possible failure/success states when running
* enforcement.
*/
- enum ActorState {
+ public enum ActorState {
ALLOWED,
INVALID_ACTOR,
MISSING_NAMESPACE,
@@ -228,53 +227,4 @@ public class OverlayActorEnforcer {
UNABLE_TO_GET_TARGET,
MISSING_LEGACY_PERMISSION
}
-
- /**
- * Delegate to the system for querying information about packages.
- */
- public interface VerifyCallback {
-
- /**
- * Read from the APK and AndroidManifest of a package to return the overlayable defined for
- * a given name.
- *
- * @throws IOException if the target can't be read
- */
- @Nullable
- OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
- @Nullable String targetOverlayableName, int userId)
- throws IOException;
-
- /**
- * @see android.content.pm.PackageManager#getPackagesForUid(int)
- */
- @Nullable
- String[] getPackagesForUid(int uid);
-
- /**
- * @param userId user to filter package visibility by
- * @see android.content.pm.PackageManager#getPackageInfo(String, int)
- */
- @Nullable
- PackageInfo getPackageInfo(@NonNull String packageName, int userId);
-
- /**
- * @return map of system pre-defined, uniquely named actors; keys are namespace,
- * value maps actor name to package name
- */
- @NonNull
- Map<String, Map<String, String>> getNamedActors();
-
- /**
- * @return true if the target package has declared an overlayable
- */
- boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
- throws RemoteException, IOException;
-
- /**
- * @throws SecurityException containing message if the caller doesn't have the given
- * permission
- */
- void enforcePermission(String permission, String message) throws SecurityException;
- }
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index f22128533ac2..c81f7cd4a8b4 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -226,7 +226,7 @@ public final class OverlayManagerService extends SystemService {
private final AtomicFile mSettingsFile;
- private final PackageManagerHelper mPackageManager;
+ private final PackageManagerHelperImpl mPackageManager;
private final UserManagerService mUserManager;
@@ -244,7 +244,7 @@ public final class OverlayManagerService extends SystemService {
traceBegin(TRACE_TAG_RRO, "OMS#OverlayManagerService");
mSettingsFile = new AtomicFile(
new File(Environment.getDataSystemDirectory(), "overlays.xml"), "overlays");
- mPackageManager = new PackageManagerHelper(context);
+ mPackageManager = new PackageManagerHelperImpl(context);
mUserManager = UserManagerService.getInstance();
IdmapManager im = new IdmapManager(mPackageManager);
mSettings = new OverlayManagerSettings();
@@ -1053,14 +1053,8 @@ public final class OverlayManagerService extends SystemService {
}
}
- /**
- * Delegate for {@link android.content.pm.PackageManager} and {@link PackageManagerInternal}
- * functionality, separated for easy testing.
- *
- * @hide
- */
- public static final class PackageManagerHelper implements
- OverlayManagerServiceImpl.PackageManagerHelper, OverlayActorEnforcer.VerifyCallback {
+ private static final class PackageManagerHelperImpl implements PackageManagerHelper,
+ OverlayableInfoCallback {
private final Context mContext;
private final IPackageManager mPackageManager;
@@ -1073,7 +1067,7 @@ public final class OverlayManagerService extends SystemService {
// behind until all pending intents have been processed.
private final SparseArray<HashMap<String, PackageInfo>> mCache = new SparseArray<>();
- PackageManagerHelper(Context context) {
+ PackageManagerHelperImpl(Context context) {
mContext = context;
mPackageManager = getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
@@ -1132,7 +1126,7 @@ public final class OverlayManagerService extends SystemService {
@Nullable
@Override
public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
- @Nullable String targetOverlayableName, int userId)
+ @NonNull String targetOverlayableName, int userId)
throws IOException {
PackageInfo packageInfo = getPackageInfo(packageName, userId);
if (packageInfo == null) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 2493057e0121..5734271ecb83 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -18,7 +18,6 @@ package com.android.server.om;
import static android.content.om.OverlayInfo.STATE_DISABLED;
import static android.content.om.OverlayInfo.STATE_ENABLED;
-import static android.content.om.OverlayInfo.STATE_ENABLED_IMMUTABLE;
import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
import static android.content.om.OverlayInfo.STATE_NO_IDMAP;
import static android.content.om.OverlayInfo.STATE_OVERLAY_IS_BEING_REPLACED;
@@ -806,11 +805,4 @@ final class OverlayManagerServiceImpl {
**/
void onOverlaysChanged(@NonNull String targetPackage, int userId);
}
-
- interface PackageManagerHelper {
- PackageInfo getPackageInfo(@NonNull String packageName, int userId);
- boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
- int userId);
- List<PackageInfo> getOverlayPackages(int userId);
- }
}
diff --git a/services/core/java/com/android/server/om/OverlayableInfoCallback.java b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
new file mode 100644
index 000000000000..6b818849c257
--- /dev/null
+++ b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.server.om;
+
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.OverlayableInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+
+import com.android.server.pm.PackageManagerServiceUtils;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Delegate to the system for querying information about overlayables and packages.
+ */
+public interface OverlayableInfoCallback {
+
+ /**
+ * Read from the APK and AndroidManifest of a package to return the overlayable defined for
+ * a given name.
+ *
+ * @throws IOException if the target can't be read
+ */
+ @Nullable
+ OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
+ @NonNull String targetOverlayableName, int userId)
+ throws IOException;
+
+ /**
+ * @see PackageManager#getPackagesForUid(int)
+ */
+ @Nullable
+ String[] getPackagesForUid(int uid);
+
+ /**
+ * @param userId user to filter package visibility by
+ * @see PackageManager#getPackageInfo(String, int)
+ */
+ @Nullable
+ PackageInfo getPackageInfo(@NonNull String packageName, int userId);
+
+ /**
+ * @return map of system pre-defined, uniquely named actors; keys are namespace,
+ * value maps actor name to package name
+ */
+ @NonNull
+ Map<String, Map<String, String>> getNamedActors();
+
+ /**
+ * @return true if the target package has declared an overlayable
+ */
+ boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
+ throws RemoteException, IOException;
+
+ /**
+ * @throws SecurityException containing message if the caller doesn't have the given
+ * permission
+ */
+ void enforcePermission(String permission, String message) throws SecurityException;
+
+ /**
+ * @return true if {@link PackageManagerServiceUtils#compareSignatures} run on both packages
+ * in the system returns {@link PackageManager#SIGNATURE_MATCH}
+ */
+ boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
+}
diff --git a/services/core/java/com/android/server/om/PackageManagerHelper.java b/services/core/java/com/android/server/om/PackageManagerHelper.java
new file mode 100644
index 000000000000..ec9c5e64e390
--- /dev/null
+++ b/services/core/java/com/android/server/om/PackageManagerHelper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.server.om;
+
+import android.annotation.NonNull;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+
+import java.util.List;
+
+/**
+ * Delegate for {@link PackageManager} and {@link PackageManagerInternal} functionality,
+ * separated for easy testing.
+ *
+ * @hide
+ */
+interface PackageManagerHelper {
+ PackageInfo getPackageInfo(@NonNull String packageName, int userId);
+ boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
+ List<PackageInfo> getOverlayPackages(int userId);
+}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
index 233e16c297a3..e08eea298aaf 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt
@@ -24,6 +24,7 @@ import android.os.Process
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
+import java.lang.UnsupportedOperationException
class OverlayActorEnforcerTests {
companion object {
@@ -159,7 +160,7 @@ class OverlayActorEnforcerTests {
private val hasPermission: Boolean = false,
private val overlayableInfo: OverlayableInfo? = null,
private vararg val packageNames: String = arrayOf("com.test.actor.one")
- ) : OverlayActorEnforcer.VerifyCallback {
+ ) : OverlayableInfoCallback {
override fun getNamedActors() = if (isActor) {
mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME))
@@ -169,7 +170,7 @@ class OverlayActorEnforcerTests {
override fun getOverlayableForTarget(
packageName: String,
- targetOverlayableName: String?,
+ targetOverlayableName: String,
userId: Int
) = overlayableInfo
@@ -193,5 +194,9 @@ class OverlayActorEnforcerTests {
throw SecurityException()
}
}
+
+ override fun signaturesMatching(pkgName1: String, pkgName2: String, userId: Int): Boolean {
+ throw UnsupportedOperationException()
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
index a428a97e51cd..cd7343235750 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
@@ -24,30 +24,16 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import android.annotation.NonNull;
import android.content.om.OverlayInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.util.ArraySet;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.content.om.OverlayConfig;
-
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
@RunWith(AndroidJUnit4.class)
public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTestsBase {
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
index a753aac39c48..820e61cb0a08 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
@@ -23,10 +23,13 @@ import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.content.om.OverlayInfo;
import android.content.om.OverlayInfo.State;
+import android.content.om.OverlayableInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.util.ArraySet;
+import androidx.annotation.Nullable;
+
import com.android.internal.content.om.OverlayConfig;
import org.junit.Before;
@@ -35,6 +38,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -281,8 +285,8 @@ class OverlayManagerServiceImplTestsBase {
}
}
- static final class DummyPackageManagerHelper implements
- OverlayManagerServiceImpl.PackageManagerHelper {
+ static final class DummyPackageManagerHelper implements PackageManagerHelper,
+ OverlayableInfoCallback {
private final DummyDeviceState mState;
private DummyPackageManagerHelper(DummyDeviceState state) {
@@ -320,6 +324,35 @@ class OverlayManagerServiceImplTestsBase {
.map(p -> getPackageInfo(p.packageName, p.userId))
.collect(Collectors.toList());
}
+
+ @Nullable
+ @Override
+ public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
+ @NonNull String targetOverlayableName, int userId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Nullable
+ @Override
+ public String[] getPackagesForUid(int uid) {
+ throw new UnsupportedOperationException();
+ }
+
+ @NonNull
+ @Override
+ public Map<String, Map<String, String>> getNamedActors() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean doesTargetDefineOverlayable(String targetPackageName, int userId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void enforcePermission(String permission, String message) throws SecurityException {
+ throw new UnsupportedOperationException();
+ }
}
static class DummyIdmapManager extends IdmapManager {
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 77e7fc55a229..9b70079a98c9 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -1007,6 +1007,9 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) {
<policy type="oem">
<item type="string" name="buz" />
</policy>
+ <policy type="actor">
+ <item type="string" name="actor" />
+ </policy>
</overlayable>)";
ASSERT_TRUE(TestParse(input));
@@ -1065,6 +1068,14 @@ TEST_F(ResourceParserTest, ParseOverlayablePolicy) {
result_overlayable_item = search_result.value().entry->overlayable_item.value();
EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name"));
EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::OEM_PARTITION));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/actor"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ ASSERT_TRUE(search_result.value().entry->overlayable_item);
+ result_overlayable_item = search_result.value().entry->overlayable_item.value();
+ EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name"));
+ EXPECT_THAT(result_overlayable_item.policies, Eq(PolicyFlags::ACTOR_SIGNATURE));
}
TEST_F(ResourceParserTest, ParseOverlayableNoPolicyError) {
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index 8a2f5afa7255..ab9ce66b0ae3 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -167,6 +167,7 @@ message OverlayableItem {
SIGNATURE = 5;
ODM = 6;
OEM = 7;
+ ACTOR = 8;
}
// The location of the <item> declaration in source.
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index e1e0f17c8dbb..59627ce579af 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -775,6 +775,7 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) {
std::string name_three = "com.app.test:integer/overlayable_three";
OverlayableItem overlayable_item_three(group_one);
overlayable_item_three.policies |= PolicyFlags::SIGNATURE;
+ overlayable_item_three.policies |= PolicyFlags::ACTOR_SIGNATURE;
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
@@ -828,7 +829,8 @@ TEST_F(TableFlattenerTest, FlattenMultipleOverlayable) {
result_overlayable = search_result.value().entry->overlayable_item.value();
EXPECT_EQ(result_overlayable.overlayable->name, "OtherName");
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization");
- EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE);
+ EXPECT_EQ(result_overlayable.policies, PolicyFlags::SIGNATURE
+ | PolicyFlags::ACTOR_SIGNATURE);
}
TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index db8e093594a0..2fd01d7f3dee 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -401,6 +401,9 @@ bool DeserializeOverlayableItemFromPb(const pb::OverlayableItem& pb_overlayable,
case pb::OverlayableItem::OEM:
out_overlayable->policies |= PolicyFlags::OEM_PARTITION;
break;
+ case pb::OverlayableItem::ACTOR:
+ out_overlayable->policies |= PolicyFlags::ACTOR_SIGNATURE;
+ break;
default:
*out_error = "unknown overlayable policy";
return false;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 6bc4524d3d5c..ba6df22af9d3 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -322,6 +322,9 @@ static void SerializeOverlayableItemToPb(const OverlayableItem& overlayable_item
if (overlayable_item.policies & PolicyFlags::OEM_PARTITION) {
pb_overlayable_item->add_policy(pb::OverlayableItem::OEM);
}
+ if (overlayable_item.policies & PolicyFlags::ACTOR_SIGNATURE) {
+ pb_overlayable_item->add_policy(pb::OverlayableItem::ACTOR);
+ }
if (source_pool != nullptr) {
SerializeSourceToPb(overlayable_item.source, source_pool,
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index cdc86597b2f3..1a7de6dc1c48 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -536,6 +536,11 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) {
overlayable_item_boz.policies |= PolicyFlags::ODM_PARTITION;
overlayable_item_boz.policies |= PolicyFlags::OEM_PARTITION;
+ OverlayableItem overlayable_item_actor_config(std::make_shared<Overlayable>(
+ "ActorConfig", "overlay://theme"));
+ overlayable_item_actor_config.policies |= PolicyFlags::SIGNATURE;
+ overlayable_item_actor_config.policies |= PolicyFlags::ACTOR_SIGNATURE;
+
OverlayableItem overlayable_item_biz(std::make_shared<Overlayable>(
"Other", "overlay://customization"));
overlayable_item_biz.comment ="comment";
@@ -548,6 +553,7 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) {
.SetOverlayable("com.app.a:bool/baz", overlayable_item_baz)
.SetOverlayable("com.app.a:bool/boz", overlayable_item_boz)
.SetOverlayable("com.app.a:bool/biz", overlayable_item_biz)
+ .SetOverlayable("com.app.a:bool/actor_config", overlayable_item_actor_config)
.AddValue("com.app.a:bool/fiz", ResourceUtils::TryParseBool("true"))
.Build();
@@ -597,6 +603,15 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) {
| PolicyFlags::ODM_PARTITION
| PolicyFlags::OEM_PARTITION));
+ search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/actor_config"));
+ ASSERT_TRUE(search_result);
+ ASSERT_TRUE(search_result.value().entry->overlayable_item);
+ overlayable_item = search_result.value().entry->overlayable_item.value();
+ EXPECT_THAT(overlayable_item.overlayable->name, Eq("ActorConfig"));
+ EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme"));
+ EXPECT_THAT(overlayable_item.policies, Eq(PolicyFlags::SIGNATURE
+ | PolicyFlags::ACTOR_SIGNATURE));
+
search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/biz"));
ASSERT_TRUE(search_result);
ASSERT_TRUE(search_result.value().entry->overlayable_item);