Persist implicit overlay configurator actor policy
This change does three things:
1) If an overlay targets a package that does not declare an overlayable
and the overlay fulfills the actor policy, the overlay can override
any resource in the target,
2) The actor policy is now implicitly granted to overlays signed with
the same signature as the configurator that target white-listed
target packages regardless of whether or not the target defines an
overlayable.
3) If an overlay was previously granted the actor policy through the
mechanism specified in (2), the overlay will continue to fulfill
the actor policy even if the configurator is removed, changes
signature, changes to a different package, or the list of
configurator targets changes. If the overlay target package or
target overlayable name changes, the persisted setting will be
reset.
Bug: 157244814
Bug: 157266239
Test: atest OverlayManagerServiceImplTests
Test: idmap2_tests
Change-Id: Iff3937849ad898b1b2d74c2c632a4cdf7690fe10
diff --git a/cmds/idmap2/libidmap2/ResourceMapping.cpp b/cmds/idmap2/libidmap2/ResourceMapping.cpp
index f82c8f1..44acbca 100644
--- a/cmds/idmap2/libidmap2/ResourceMapping.cpp
+++ b/cmds/idmap2/libidmap2/ResourceMapping.cpp
@@ -61,7 +61,8 @@
const ResourceId& target_resource) {
static constexpr const PolicyBitmask sDefaultPolicies =
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
- PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE;
+ PolicyFlags::VENDOR_PARTITION | PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE |
+ PolicyFlags::ACTOR_SIGNATURE;
// If the resource does not have an overlayable definition, allow the resource to be overlaid if
// the overlay is preinstalled or signed with the same signature as the target.
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index de039f4..5754eaf 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -287,66 +287,26 @@
R::overlay::string::str4, false /* rewrite */));
}
-// Overlays that are neither pre-installed nor signed with the same signature as the target cannot
+
+// Overlays that are pre-installed or are signed with the same signature as the target/actor can
// overlay packages that have not defined overlayable resources.
-TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
- auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
- "/overlay/overlay-no-name.apk", PolicyFlags::PUBLIC,
- /* enforce_overlayable */ true);
-
- ASSERT_TRUE(resources) << resources.GetErrorMessage();
- ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
-}
-
-// Overlays that are pre-installed or are signed with the same signature as the target can overlay
-// packages that have not defined overlayable resources.
TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
- auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
+ constexpr PolicyBitmask kDefaultPolicies =
+ PolicyFlags::SIGNATURE | PolicyFlags::ACTOR_SIGNATURE | PolicyFlags::PRODUCT_PARTITION |
+ PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION | PolicyFlags::ODM_PARTITION |
+ PolicyFlags::OEM_PARTITION;
+
+ for (PolicyBitmask policy = 1U << (sizeof(PolicyBitmask) * 8 - 1); policy > 0;
+ policy = policy >> 1U) {
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
"/system-overlay-invalid/system-overlay-invalid.apk",
- fulfilled_policies,
- /* enforce_overlayable */ true);
-
+ policy, /* enforce_overlayable */ true);
ASSERT_TRUE(resources) << resources.GetErrorMessage();
- auto& res = *resources;
- 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 */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_oem,
- false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_product, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_product,
- false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_public, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_public,
- false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_signature,
- false /* rewrite */));
- ASSERT_RESULT(MappingExists(res, R::target::string::policy_system, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_system,
- false /* rewrite */));
- ASSERT_RESULT(MappingExists(
- res, R::target::string::policy_system_vendor, Res_value::TYPE_REFERENCE,
- R::system_overlay_invalid::string::policy_system_vendor, false /* rewrite */));
- };
- CheckEntries(PolicyFlags::SIGNATURE);
- CheckEntries(PolicyFlags::PRODUCT_PARTITION);
- CheckEntries(PolicyFlags::SYSTEM_PARTITION);
- CheckEntries(PolicyFlags::VENDOR_PARTITION);
- CheckEntries(PolicyFlags::ODM_PARTITION);
- CheckEntries(PolicyFlags::OEM_PARTITION);
+ const size_t expected_overlaid = (policy & kDefaultPolicies) != 0 ? 10U : 0U;
+ ASSERT_EQ(expected_overlaid, resources->GetTargetToOverlayMap().size())
+ << "Incorrect number of resources overlaid through policy " << policy;
+ }
}
} // namespace android::idmap2
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 735d669..59735eb 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -29,18 +29,15 @@
import android.os.SystemProperties;
import android.util.Slog;
-import com.android.internal.util.ArrayUtils;
-
import java.io.IOException;
/**
* Handle the creation and deletion of idmap files.
*
- * The actual work is performed by the idmap binary, launched through idmap2d.
- *
- * Note: this class is subclassed in the OMS unit tests, and hence not marked as final.
+ * The actual work is performed by idmap2d.
+ * @see IdmapDaemon
*/
-class IdmapManager {
+final class IdmapManager {
private static final boolean VENDOR_IS_Q_OR_LATER;
static {
final String value = SystemProperties.get("ro.vndk.version", "29");
@@ -57,14 +54,10 @@
private final IdmapDaemon mIdmapDaemon;
private final OverlayableInfoCallback mOverlayableCallback;
- private final String mOverlayableConfigurator;
- private final String[] mOverlayableConfiguratorTargets;
IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
mOverlayableCallback = verifyCallback;
mIdmapDaemon = idmapDaemon;
- mOverlayableConfigurator = verifyCallback.getOverlayableConfigurator();
- mOverlayableConfiguratorTargets = verifyCallback.getOverlayableConfiguratorTargets() ;
}
/**
@@ -72,7 +65,7 @@
* modified.
*/
boolean createIdmap(@NonNull final PackageInfo targetPackage,
- @NonNull final PackageInfo overlayPackage, int userId) {
+ @NonNull final PackageInfo overlayPackage, int additionalPolicies, int userId) {
if (DEBUG) {
Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
+ overlayPackage.packageName);
@@ -80,13 +73,14 @@
final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
try {
- int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
boolean enforce = enforceOverlayable(overlayPackage);
+ int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId)
+ | additionalPolicies;
if (mIdmapDaemon.verifyIdmap(targetPath, overlayPath, policies, enforce, userId)) {
return false;
}
- return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
- enforce, userId) != null;
+ return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, enforce, userId)
+ != null;
} catch (Exception e) {
Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
+ overlayPath + ": " + e.getMessage());
@@ -190,14 +184,6 @@
String targetOverlayableName = overlayPackage.targetOverlayableName;
if (targetOverlayableName != null) {
try {
- if (!mOverlayableConfigurator.isEmpty()
- && ArrayUtils.contains(mOverlayableConfiguratorTargets,
- targetPackage.packageName)
- && mOverlayableCallback.signaturesMatching(mOverlayableConfigurator,
- overlayPackage.packageName, userId)) {
- return true;
- }
-
OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
targetPackage.packageName, targetOverlayableName, userId);
if (overlayableInfo != null && overlayableInfo.actor != null) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 086ab81..3c5e476 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -252,7 +252,8 @@
mSettings = new OverlayManagerSettings();
mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
OverlayConfig.getSystemInstance(), getDefaultOverlayPackages(),
- new OverlayChangeListener());
+ new OverlayChangeListener(), getOverlayableConfigurator(),
+ getOverlayableConfiguratorTargets());
mActorEnforcer = new OverlayActorEnforcer(mPackageManager);
final IntentFilter packageFilter = new IntentFilter();
@@ -335,6 +336,28 @@
return defaultPackages.toArray(new String[defaultPackages.size()]);
}
+
+ /**
+ * Retrieves the package name that is recognized as an actor for the packages specified by
+ * {@link #getOverlayableConfiguratorTargets()}.
+ */
+ @Nullable
+ private String getOverlayableConfigurator() {
+ return TextUtils.nullIfEmpty(Resources.getSystem()
+ .getString(R.string.config_overlayableConfigurator));
+ }
+
+ /**
+ * Retrieves the target packages that recognize the {@link #getOverlayableConfigurator} as an
+ * actor for itself. Overlays targeting one of the specified targets that are signed with the
+ * same signature as the overlayable configurator will be granted the "actor" policy.
+ */
+ @Nullable
+ private String[] getOverlayableConfiguratorTargets() {
+ return Resources.getSystem().getStringArray(
+ R.array.config_overlayableConfiguratorTargets);
+ }
+
private final class PackageReceiver extends BroadcastReceiver {
@Override
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
@@ -1121,17 +1144,6 @@
}
@Override
- public String getOverlayableConfigurator() {
- return Resources.getSystem().getString(R.string.config_overlayableConfigurator);
- }
-
- @Override
- public String[] getOverlayableConfiguratorTargets() {
- return Resources.getSystem().getStringArray(
- R.array.config_overlayableConfiguratorTargets);
- }
-
- @Override
public List<PackageInfo> getOverlayPackages(final int userId) {
final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);
for (final PackageInfo info : overlays) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 05a4a38..879ad4f 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -31,6 +31,7 @@
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
+import android.os.OverlayablePolicy;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -73,6 +74,9 @@
private final String[] mDefaultOverlays;
private final OverlayChangeListener mListener;
+ private final String mOverlayableConfigurator;
+ private final String[] mOverlayableConfiguratorTargets;
+
/**
* Helper method to merge the overlay manager's (as read from overlays.xml)
* and package manager's (as parsed from AndroidManifest.xml files) views
@@ -115,13 +119,17 @@
@NonNull final OverlayManagerSettings settings,
@NonNull final OverlayConfig overlayConfig,
@NonNull final String[] defaultOverlays,
- @NonNull final OverlayChangeListener listener) {
+ @NonNull final OverlayChangeListener listener,
+ @Nullable final String overlayableConfigurator,
+ @Nullable final String[] overlayableConfiguratorTargets) {
mPackageManager = packageManager;
mIdmapManager = idmapManager;
mSettings = settings;
mOverlayConfig = overlayConfig;
mDefaultOverlays = defaultOverlays;
mListener = listener;
+ mOverlayableConfigurator = overlayableConfigurator;
+ mOverlayableConfiguratorTargets = overlayableConfiguratorTargets;
}
/**
@@ -706,7 +714,25 @@
if (targetPackage != null && overlayPackage != null
&& !("android".equals(targetPackageName)
&& !isPackageConfiguredMutable(overlayPackageName))) {
- modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
+
+ int additionalPolicies = 0;
+ if (TextUtils.nullIfEmpty(mOverlayableConfigurator) != null
+ && ArrayUtils.contains(mOverlayableConfiguratorTargets, targetPackageName)
+ && isPackageConfiguredMutable(overlayPackageName)
+ && mPackageManager.signaturesMatching(mOverlayableConfigurator,
+ overlayPackageName, userId)) {
+ // The overlay targets a package that has the overlayable configurator configured as
+ // its actor. The overlay and this actor are signed with the same signature, so
+ // the overlay fulfills the actor policy.
+ modified |= mSettings.setHasConfiguratorActorPolicy(overlayPackageName, userId,
+ true);
+ additionalPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
+ } else if (mSettings.hasConfiguratorActorPolicy(overlayPackageName, userId)) {
+ additionalPolicies |= OverlayablePolicy.ACTOR_SIGNATURE;
+ }
+
+ modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage, additionalPolicies,
+ userId);
}
if (overlayPackage != null) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index bdbaf78..f8226fa 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -73,7 +73,7 @@
remove(packageName, userId);
insert(new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
baseCodePath, OverlayInfo.STATE_UNKNOWN, isEnabled, isMutable, priority,
- overlayCategory));
+ overlayCategory, false /* hasConfiguratorActorPolicy */));
}
/**
@@ -160,6 +160,26 @@
return mItems.get(idx).setState(state);
}
+ boolean hasConfiguratorActorPolicy(@NonNull final String packageName, final int userId) {
+ final int idx = select(packageName, userId);
+ if (idx < 0) {
+ throw new BadKeyException(packageName, userId);
+ }
+ return mItems.get(idx).hasConfiguratorActorPolicy();
+ }
+
+ /**
+ * Returns true if the settings were modified, false if they remain the same.
+ */
+ boolean setHasConfiguratorActorPolicy(@NonNull final String packageName, final int userId,
+ boolean hasPolicy) {
+ final int idx = select(packageName, userId);
+ if (idx < 0) {
+ throw new BadKeyException(packageName, userId);
+ }
+ return mItems.get(idx).setHasConfiguratorActorPolicy(hasPolicy);
+ }
+
List<OverlayInfo> getOverlaysForTarget(@NonNull final String targetPackageName,
final int userId) {
// Immutable RROs targeting "android" are loaded from AssetManager, and so they should be
@@ -323,16 +343,17 @@
pw.println(item.mPackageName + ":" + item.getUserId() + " {");
pw.increaseIndent();
- pw.println("mPackageName...........: " + item.mPackageName);
- pw.println("mUserId................: " + item.getUserId());
- pw.println("mTargetPackageName.....: " + item.getTargetPackageName());
- pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName());
- pw.println("mBaseCodePath..........: " + item.getBaseCodePath());
- pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
- pw.println("mIsEnabled.............: " + item.isEnabled());
- pw.println("mIsMutable.............: " + item.isMutable());
- pw.println("mPriority..............: " + item.mPriority);
- pw.println("mCategory..............: " + item.mCategory);
+ pw.println("mPackageName................: " + item.mPackageName);
+ pw.println("mUserId.....................: " + item.getUserId());
+ pw.println("mTargetPackageName..........: " + item.getTargetPackageName());
+ pw.println("mTargetOverlayableName......: " + item.getTargetOverlayableName());
+ pw.println("mBaseCodePath...............: " + item.getBaseCodePath());
+ pw.println("mState......................: " + OverlayInfo.stateToString(item.getState()));
+ pw.println("mIsEnabled..................: " + item.isEnabled());
+ pw.println("mIsMutable..................: " + item.isMutable());
+ pw.println("mPriority...................: " + item.mPriority);
+ pw.println("mCategory...................: " + item.mCategory);
+ pw.println("mHasConfiguratorActorPolicy.: " + item.hasConfiguratorActorPolicy());
pw.decreaseIndent();
pw.println("}");
@@ -371,6 +392,9 @@
case "category":
pw.println(item.mCategory);
break;
+ case "hasconfiguratoractorpolicy":
+ pw.println(item.mHasConfiguratorActorPolicy);
+ break;
}
}
@@ -398,9 +422,11 @@
private static final String ATTR_CATEGORY = "category";
private static final String ATTR_USER_ID = "userId";
private static final String ATTR_VERSION = "version";
+ private static final String ATTR_HAS_CONFIGURATOR_ACTOR_POLICY =
+ "hasConfiguratorActorPolicy";
@VisibleForTesting
- static final int CURRENT_VERSION = 3;
+ static final int CURRENT_VERSION = 4;
public static void restore(@NonNull final ArrayList<SettingsItem> table,
@NonNull final InputStream is) throws IOException, XmlPullParserException {
@@ -454,9 +480,12 @@
final boolean isStatic = XmlUtils.readBooleanAttribute(parser, ATTR_IS_STATIC);
final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY);
final String category = XmlUtils.readStringAttribute(parser, ATTR_CATEGORY);
+ final boolean hasConfiguratorActorPolicy = XmlUtils.readBooleanAttribute(parser,
+ ATTR_HAS_CONFIGURATOR_ACTOR_POLICY);
return new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
- baseCodePath, state, isEnabled, !isStatic, priority, category);
+ baseCodePath, state, isEnabled, !isStatic, priority, category,
+ hasConfiguratorActorPolicy);
}
public static void persist(@NonNull final ArrayList<SettingsItem> table,
@@ -491,6 +520,8 @@
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_STATIC, !item.mIsMutable);
XmlUtils.writeIntAttribute(xml, ATTR_PRIORITY, item.mPriority);
XmlUtils.writeStringAttribute(xml, ATTR_CATEGORY, item.mCategory);
+ XmlUtils.writeBooleanAttribute(xml, ATTR_HAS_CONFIGURATOR_ACTOR_POLICY,
+ item.mHasConfiguratorActorPolicy);
xml.endTag(null, TAG_ITEM);
}
}
@@ -507,12 +538,14 @@
private boolean mIsMutable;
private int mPriority;
private String mCategory;
+ private boolean mHasConfiguratorActorPolicy;
SettingsItem(@NonNull final String packageName, final int userId,
@NonNull final String targetPackageName,
@Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
final @OverlayInfo.State int state, final boolean isEnabled,
- final boolean isMutable, final int priority, @Nullable String category) {
+ final boolean isMutable, final int priority, @Nullable String category,
+ final boolean hasConfiguratorActorPolicy) {
mPackageName = packageName;
mUserId = userId;
mTargetPackageName = targetPackageName;
@@ -524,6 +557,7 @@
mCache = null;
mIsMutable = isMutable;
mPriority = priority;
+ mHasConfiguratorActorPolicy = hasConfiguratorActorPolicy;
}
private String getTargetPackageName() {
@@ -614,6 +648,18 @@
private int getPriority() {
return mPriority;
}
+
+ private boolean hasConfiguratorActorPolicy() {
+ return mHasConfiguratorActorPolicy;
+ }
+
+ private boolean setHasConfiguratorActorPolicy(boolean hasPolicy) {
+ if (mHasConfiguratorActorPolicy != hasPolicy) {
+ mHasConfiguratorActorPolicy = hasPolicy;
+ return true;
+ }
+ return false;
+ }
}
private int select(@NonNull final String packageName, final int userId) {
diff --git a/services/core/java/com/android/server/om/OverlayableInfoCallback.java b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
index 41c341a..5066ecd 100644
--- a/services/core/java/com/android/server/om/OverlayableInfoCallback.java
+++ b/services/core/java/com/android/server/om/OverlayableInfoCallback.java
@@ -80,24 +80,4 @@
* in the system returns {@link PackageManager#SIGNATURE_MATCH}
*/
boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
-
- /**
- * Retrieves the package name that is recognized as an actor for the packages specified by
- * {@link #getOverlayableConfiguratorTargets()}.
- */
- @NonNull
- default String getOverlayableConfigurator() {
- return "";
- }
-
- /**
- * Retrieves the target packages that recognize the {@link #getOverlayableConfigurator} as an
- * actor for its overlayable declarations. Overlays targeting one of the specified targets that
- * are signed with the same signature as the overlayable configurator will be granted the
- * "actor" policy.
- */
- @NonNull
- default String[] getOverlayableConfiguratorTargets() {
- return new String[0];
- }
}
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 b25af05..8774ab0 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTests.java
@@ -208,45 +208,134 @@
@Test
public void testConfigurator() {
- final DummyPackageManagerHelper packageManager = getPackageManager();
- packageManager.overlayableConfigurator = "actor";
- packageManager.overlayableConfiguratorTargets = new String[]{TARGET};
+ mOverlayableConfigurator = "actor";
+ mOverlayableConfiguratorTargets = new String[]{TARGET};
reinitializeImpl();
installNewPackage(target("actor").setCertificate("one"), USER);
- installNewPackage(target(TARGET)
- .addOverlayable("TestResources")
- .setCertificate("two"), USER);
+ installNewPackage(target(TARGET).addOverlayable("TestResources").setCertificate("two"),
+ USER);
- final DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
+ DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
.setCertificate("one");
installNewPackage(overlay, USER);
- final DummyIdmapDaemon idmapDaemon = getIdmapDaemon();
- final DummyIdmapDaemon.IdmapHeader idmap = idmapDaemon.getIdmap(overlay.build().apkPath);
+ DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
assertNotNull(idmap);
assertEquals(OverlayablePolicy.ACTOR_SIGNATURE,
idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
}
@Test
- public void testConfiguratorDifferentSignatures() {
- final DummyPackageManagerHelper packageManager = getPackageManager();
- packageManager.overlayableConfigurator = "actor";
- packageManager.overlayableConfiguratorTargets = new String[]{TARGET};
+ public void testConfiguratorWithoutOverlayable() {
+ mOverlayableConfigurator = "actor";
+ mOverlayableConfiguratorTargets = new String[]{TARGET};
reinitializeImpl();
installNewPackage(target("actor").setCertificate("one"), USER);
- installNewPackage(target(TARGET)
- .addOverlayable("TestResources")
- .setCertificate("two"), USER);
+ installNewPackage(target(TARGET).setCertificate("two"), USER);
- final DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
+ DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET).setCertificate("one");
+ installNewPackage(overlay, USER);
+
+ DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
+ assertNotNull(idmap);
+ assertEquals(OverlayablePolicy.ACTOR_SIGNATURE,
+ idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
+ }
+
+ @Test
+ public void testConfiguratorDifferentTargets() {
+ // The target package is not listed in the configurator target list, so the actor policy
+ // should not be granted.
+ mOverlayableConfigurator = "actor";
+ mOverlayableConfiguratorTargets = new String[]{"somethingElse"};
+ reinitializeImpl();
+
+ installNewPackage(target("actor").setCertificate("one"), USER);
+ installNewPackage(target(TARGET).setCertificate("two"), USER);
+
+ DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET).setCertificate("one");
+ installNewPackage(overlay, USER);
+
+ DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
+ assertNotNull(idmap);
+ assertEquals(0, idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
+ }
+
+ @Test
+ public void testConfiguratorDifferentSignatures() {
+ mOverlayableConfigurator = "actor";
+ mOverlayableConfiguratorTargets = new String[]{TARGET};
+ reinitializeImpl();
+
+ installNewPackage(target("actor").setCertificate("one"), USER);
+ installNewPackage(target(TARGET).addOverlayable("TestResources").setCertificate("two"),
+ USER);
+
+ DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
.setCertificate("two");
installNewPackage(overlay, USER);
- final DummyIdmapDaemon idmapDaemon = getIdmapDaemon();
- final DummyIdmapDaemon.IdmapHeader idmap = idmapDaemon.getIdmap(overlay.build().apkPath);
+ DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
+ assertNotNull(idmap);
+ assertEquals(0, idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
+ }
+
+ @Test
+ public void testConfiguratorWithoutOverlayableDifferentSignatures() {
+ mOverlayableConfigurator = "actor";
+ mOverlayableConfiguratorTargets = new String[]{TARGET};
+ reinitializeImpl();
+
+ installNewPackage(target("actor").setCertificate("one"), USER);
+ installNewPackage(target(TARGET).setCertificate("two"), USER);
+
+ DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET).setCertificate("two");
+ installNewPackage(overlay, USER);
+
+ DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
+ assertNotNull(idmap);
+ assertEquals(0, idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
+ }
+
+ @Test
+ public void testConfiguratorChanges() {
+ mOverlayableConfigurator = "actor";
+ mOverlayableConfiguratorTargets = new String[]{TARGET};
+ reinitializeImpl();
+
+ installNewPackage(target("actor").setCertificate("one"), USER);
+ installNewPackage(target(TARGET).addOverlayable("TestResources").setCertificate("two"),
+ USER);
+
+ DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
+ .setCertificate("one");
+ installNewPackage(overlay, USER);
+
+ DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
+ assertNotNull(idmap);
+ assertEquals(OverlayablePolicy.ACTOR_SIGNATURE,
+ idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
+
+ // Change the configurator to a different package. The overlay should still be granted the
+ // actor policy.
+ mOverlayableConfigurator = "differentActor";
+ OverlayManagerServiceImpl impl = reinitializeImpl();
+ impl.updateOverlaysForUser(USER);
+
+ idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
+ assertNotNull(idmap);
+ assertEquals(OverlayablePolicy.ACTOR_SIGNATURE,
+ idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
+
+ // Reset the setting persisting that the overlay once fulfilled the actor policy implicitly
+ // through the configurator. The overlay should lose the actor policy.
+ impl = reinitializeImpl();
+ getSettings().setHasConfiguratorActorPolicy(OVERLAY, USER, false);
+ impl.updateOverlaysForUser(USER);
+
+ idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
assertNotNull(idmap);
assertEquals(0, idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
}
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 ec6a481..52a5890 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplTestsBase.java
@@ -42,7 +42,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.stream.Collectors;
/** Base class for creating {@link OverlayManagerServiceImplTests} tests. */
@@ -53,6 +52,9 @@
private DummyPackageManagerHelper mPackageManager;
private DummyIdmapDaemon mIdmapDaemon;
private OverlayConfig mOverlayConfig;
+ private OverlayManagerSettings mSettings;
+ String mOverlayableConfigurator;
+ String[] mOverlayableConfiguratorTargets;
@Before
public void setUp() {
@@ -60,20 +62,26 @@
mListener = new DummyListener();
mPackageManager = new DummyPackageManagerHelper(mState);
mIdmapDaemon = new DummyIdmapDaemon(mState);
+ mSettings = new OverlayManagerSettings();
mOverlayConfig = mock(OverlayConfig.class);
when(mOverlayConfig.getPriority(any())).thenReturn(OverlayConfig.DEFAULT_PRIORITY);
when(mOverlayConfig.isEnabled(any())).thenReturn(false);
when(mOverlayConfig.isMutable(any())).thenReturn(true);
+ mOverlayableConfigurator = null;
+ mOverlayableConfiguratorTargets = null;
reinitializeImpl();
}
- void reinitializeImpl() {
+ OverlayManagerServiceImpl reinitializeImpl() {
mImpl = new OverlayManagerServiceImpl(mPackageManager,
new IdmapManager(mIdmapDaemon, mPackageManager),
- new OverlayManagerSettings(),
+ mSettings,
mOverlayConfig,
new String[0],
- mListener);
+ mListener,
+ mOverlayableConfigurator,
+ mOverlayableConfiguratorTargets);
+ return mImpl;
}
OverlayManagerServiceImpl getImpl() {
@@ -84,14 +92,14 @@
return mListener;
}
- DummyPackageManagerHelper getPackageManager() {
- return mPackageManager;
- }
-
DummyIdmapDaemon getIdmapDaemon() {
return mIdmapDaemon;
}
+ OverlayManagerSettings getSettings() {
+ return mSettings;
+ }
+
void assertState(@State int expected, final String overlayPackageName, int userId) {
final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
if (info == null) {
@@ -314,8 +322,6 @@
static final class DummyPackageManagerHelper implements PackageManagerHelper,
OverlayableInfoCallback {
private final DummyDeviceState mState;
- String[] overlayableConfiguratorTargets = new String[0];
- String overlayableConfigurator = "";
private DummyPackageManagerHelper(DummyDeviceState state) {
mState = state;
@@ -387,16 +393,6 @@
public void enforcePermission(String permission, String message) throws SecurityException {
throw new UnsupportedOperationException();
}
-
- @Override
- public String[] getOverlayableConfiguratorTargets() {
- return overlayableConfiguratorTargets;
- }
-
- @Override
- public String getOverlayableConfigurator() {
- return overlayableConfigurator;
- }
}
static class DummyIdmapDaemon extends IdmapDaemon {
@@ -433,7 +429,8 @@
if (idmap == null) {
return false;
}
- return idmap.isUpToDate(getCrc(targetPath), getCrc(overlayPath), targetPath);
+ return idmap.isUpToDate(getCrc(targetPath), getCrc(overlayPath), targetPath, policies,
+ enforce);
}
@Override
@@ -462,9 +459,11 @@
}
private boolean isUpToDate(int expectedTargetCrc, int expectedOverlayCrc,
- String expectedTargetPath) {
+ String expectedTargetPath, int expectedPolicies,
+ boolean expectedEnforceOverlayable) {
return expectedTargetCrc == targetCrc && expectedOverlayCrc == overlayCrc
- && expectedTargetPath.equals(targetPath);
+ && expectedTargetPath.equals(targetPath) && expectedPolicies == policies
+ && expectedEnforceOverlayable == enforceOverlayable;
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java
index 146f60a..e2cedb5 100644
--- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerSettingsTests.java
@@ -367,7 +367,8 @@
+ " isEnabled='false'\n"
+ " category='dummy-category'\n"
+ " isStatic='false'\n"
- + " priority='0' />\n"
+ + " priority='0'"
+ + " hasConfiguratorActorPolicy='true' />\n"
+ "</overlays>\n";
ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes("utf-8"));
@@ -380,6 +381,7 @@
assertEquals(1234, oi.userId);
assertEquals(STATE_DISABLED, oi.state);
assertFalse(mSettings.getEnabled("com.dummy.overlay", 1234));
+ assertTrue(mSettings.hasConfiguratorActorPolicy("com.dummy.overlay", 1234));
}
@Test