Merge "Persist implicit overlay configurator actor policy" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
41b850d0a8
@@ -61,7 +61,8 @@ Result<Unit> CheckOverlayable(const LoadedPackage& target_package,
|
|||||||
const ResourceId& target_resource) {
|
const ResourceId& target_resource) {
|
||||||
static constexpr const PolicyBitmask sDefaultPolicies =
|
static constexpr const PolicyBitmask sDefaultPolicies =
|
||||||
PolicyFlags::ODM_PARTITION | PolicyFlags::OEM_PARTITION | PolicyFlags::SYSTEM_PARTITION |
|
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
|
// 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.
|
// the overlay is preinstalled or signed with the same signature as the target.
|
||||||
|
|||||||
@@ -287,66 +287,26 @@ TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTarget
|
|||||||
R::overlay::string::str4, false /* rewrite */));
|
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.
|
// 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) {
|
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",
|
auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
|
||||||
"/system-overlay-invalid/system-overlay-invalid.apk",
|
"/system-overlay-invalid/system-overlay-invalid.apk",
|
||||||
fulfilled_policies,
|
policy, /* enforce_overlayable */ true);
|
||||||
/* enforce_overlayable */ true);
|
|
||||||
|
|
||||||
ASSERT_TRUE(resources) << resources.GetErrorMessage();
|
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);
|
const size_t expected_overlaid = (policy & kDefaultPolicies) != 0 ? 10U : 0U;
|
||||||
CheckEntries(PolicyFlags::PRODUCT_PARTITION);
|
ASSERT_EQ(expected_overlaid, resources->GetTargetToOverlayMap().size())
|
||||||
CheckEntries(PolicyFlags::SYSTEM_PARTITION);
|
<< "Incorrect number of resources overlaid through policy " << policy;
|
||||||
CheckEntries(PolicyFlags::VENDOR_PARTITION);
|
}
|
||||||
CheckEntries(PolicyFlags::ODM_PARTITION);
|
|
||||||
CheckEntries(PolicyFlags::OEM_PARTITION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace android::idmap2
|
} // namespace android::idmap2
|
||||||
|
|||||||
@@ -29,18 +29,15 @@ import android.os.OverlayablePolicy;
|
|||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import com.android.internal.util.ArrayUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the creation and deletion of idmap files.
|
* Handle the creation and deletion of idmap files.
|
||||||
*
|
*
|
||||||
* The actual work is performed by the idmap binary, launched through idmap2d.
|
* The actual work is performed by idmap2d.
|
||||||
*
|
* @see IdmapDaemon
|
||||||
* Note: this class is subclassed in the OMS unit tests, and hence not marked as final.
|
|
||||||
*/
|
*/
|
||||||
class IdmapManager {
|
final class IdmapManager {
|
||||||
private static final boolean VENDOR_IS_Q_OR_LATER;
|
private static final boolean VENDOR_IS_Q_OR_LATER;
|
||||||
static {
|
static {
|
||||||
final String value = SystemProperties.get("ro.vndk.version", "29");
|
final String value = SystemProperties.get("ro.vndk.version", "29");
|
||||||
@@ -57,14 +54,10 @@ class IdmapManager {
|
|||||||
|
|
||||||
private final IdmapDaemon mIdmapDaemon;
|
private final IdmapDaemon mIdmapDaemon;
|
||||||
private final OverlayableInfoCallback mOverlayableCallback;
|
private final OverlayableInfoCallback mOverlayableCallback;
|
||||||
private final String mOverlayableConfigurator;
|
|
||||||
private final String[] mOverlayableConfiguratorTargets;
|
|
||||||
|
|
||||||
IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
|
IdmapManager(final IdmapDaemon idmapDaemon, final OverlayableInfoCallback verifyCallback) {
|
||||||
mOverlayableCallback = verifyCallback;
|
mOverlayableCallback = verifyCallback;
|
||||||
mIdmapDaemon = idmapDaemon;
|
mIdmapDaemon = idmapDaemon;
|
||||||
mOverlayableConfigurator = verifyCallback.getOverlayableConfigurator();
|
|
||||||
mOverlayableConfiguratorTargets = verifyCallback.getOverlayableConfiguratorTargets() ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,7 +65,7 @@ class IdmapManager {
|
|||||||
* modified.
|
* modified.
|
||||||
*/
|
*/
|
||||||
boolean createIdmap(@NonNull final PackageInfo targetPackage,
|
boolean createIdmap(@NonNull final PackageInfo targetPackage,
|
||||||
@NonNull final PackageInfo overlayPackage, int userId) {
|
@NonNull final PackageInfo overlayPackage, int additionalPolicies, int userId) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
|
Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
|
||||||
+ overlayPackage.packageName);
|
+ overlayPackage.packageName);
|
||||||
@@ -80,13 +73,14 @@ class IdmapManager {
|
|||||||
final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
|
final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
|
||||||
final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
|
final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
|
||||||
try {
|
try {
|
||||||
int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
|
|
||||||
boolean enforce = enforceOverlayable(overlayPackage);
|
boolean enforce = enforceOverlayable(overlayPackage);
|
||||||
|
int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId)
|
||||||
|
| additionalPolicies;
|
||||||
if (mIdmapDaemon.verifyIdmap(targetPath, overlayPath, policies, enforce, userId)) {
|
if (mIdmapDaemon.verifyIdmap(targetPath, overlayPath, policies, enforce, userId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies,
|
return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, enforce, userId)
|
||||||
enforce, userId) != null;
|
!= null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
|
Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
|
||||||
+ overlayPath + ": " + e.getMessage());
|
+ overlayPath + ": " + e.getMessage());
|
||||||
@@ -190,14 +184,6 @@ class IdmapManager {
|
|||||||
String targetOverlayableName = overlayPackage.targetOverlayableName;
|
String targetOverlayableName = overlayPackage.targetOverlayableName;
|
||||||
if (targetOverlayableName != null) {
|
if (targetOverlayableName != null) {
|
||||||
try {
|
try {
|
||||||
if (!mOverlayableConfigurator.isEmpty()
|
|
||||||
&& ArrayUtils.contains(mOverlayableConfiguratorTargets,
|
|
||||||
targetPackage.packageName)
|
|
||||||
&& mOverlayableCallback.signaturesMatching(mOverlayableConfigurator,
|
|
||||||
overlayPackage.packageName, userId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
|
OverlayableInfo overlayableInfo = mOverlayableCallback.getOverlayableForTarget(
|
||||||
targetPackage.packageName, targetOverlayableName, userId);
|
targetPackage.packageName, targetOverlayableName, userId);
|
||||||
if (overlayableInfo != null && overlayableInfo.actor != null) {
|
if (overlayableInfo != null && overlayableInfo.actor != null) {
|
||||||
|
|||||||
@@ -252,7 +252,8 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
mSettings = new OverlayManagerSettings();
|
mSettings = new OverlayManagerSettings();
|
||||||
mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
|
mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
|
||||||
OverlayConfig.getSystemInstance(), getDefaultOverlayPackages(),
|
OverlayConfig.getSystemInstance(), getDefaultOverlayPackages(),
|
||||||
new OverlayChangeListener());
|
new OverlayChangeListener(), getOverlayableConfigurator(),
|
||||||
|
getOverlayableConfiguratorTargets());
|
||||||
mActorEnforcer = new OverlayActorEnforcer(mPackageManager);
|
mActorEnforcer = new OverlayActorEnforcer(mPackageManager);
|
||||||
|
|
||||||
final IntentFilter packageFilter = new IntentFilter();
|
final IntentFilter packageFilter = new IntentFilter();
|
||||||
@@ -335,6 +336,28 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
return defaultPackages.toArray(new String[defaultPackages.size()]);
|
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 {
|
private final class PackageReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
|
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
|
||||||
@@ -1120,17 +1143,6 @@ public final class OverlayManagerService extends SystemService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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
|
@Override
|
||||||
public List<PackageInfo> getOverlayPackages(final int userId) {
|
public List<PackageInfo> getOverlayPackages(final int userId) {
|
||||||
final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);
|
final List<PackageInfo> overlays = mPackageManagerInternal.getOverlayPackages(userId);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import android.annotation.Nullable;
|
|||||||
import android.content.om.OverlayInfo;
|
import android.content.om.OverlayInfo;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.os.OverlayablePolicy;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -73,6 +74,9 @@ final class OverlayManagerServiceImpl {
|
|||||||
private final String[] mDefaultOverlays;
|
private final String[] mDefaultOverlays;
|
||||||
private final OverlayChangeListener mListener;
|
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)
|
* Helper method to merge the overlay manager's (as read from overlays.xml)
|
||||||
* and package manager's (as parsed from AndroidManifest.xml files) views
|
* and package manager's (as parsed from AndroidManifest.xml files) views
|
||||||
@@ -115,13 +119,17 @@ final class OverlayManagerServiceImpl {
|
|||||||
@NonNull final OverlayManagerSettings settings,
|
@NonNull final OverlayManagerSettings settings,
|
||||||
@NonNull final OverlayConfig overlayConfig,
|
@NonNull final OverlayConfig overlayConfig,
|
||||||
@NonNull final String[] defaultOverlays,
|
@NonNull final String[] defaultOverlays,
|
||||||
@NonNull final OverlayChangeListener listener) {
|
@NonNull final OverlayChangeListener listener,
|
||||||
|
@Nullable final String overlayableConfigurator,
|
||||||
|
@Nullable final String[] overlayableConfiguratorTargets) {
|
||||||
mPackageManager = packageManager;
|
mPackageManager = packageManager;
|
||||||
mIdmapManager = idmapManager;
|
mIdmapManager = idmapManager;
|
||||||
mSettings = settings;
|
mSettings = settings;
|
||||||
mOverlayConfig = overlayConfig;
|
mOverlayConfig = overlayConfig;
|
||||||
mDefaultOverlays = defaultOverlays;
|
mDefaultOverlays = defaultOverlays;
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
|
mOverlayableConfigurator = overlayableConfigurator;
|
||||||
|
mOverlayableConfiguratorTargets = overlayableConfiguratorTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -706,7 +714,25 @@ final class OverlayManagerServiceImpl {
|
|||||||
if (targetPackage != null && overlayPackage != null
|
if (targetPackage != null && overlayPackage != null
|
||||||
&& !("android".equals(targetPackageName)
|
&& !("android".equals(targetPackageName)
|
||||||
&& !isPackageConfiguredMutable(overlayPackageName))) {
|
&& !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) {
|
if (overlayPackage != null) {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ final class OverlayManagerSettings {
|
|||||||
remove(packageName, userId);
|
remove(packageName, userId);
|
||||||
insert(new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
|
insert(new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
|
||||||
baseCodePath, OverlayInfo.STATE_UNKNOWN, isEnabled, isMutable, priority,
|
baseCodePath, OverlayInfo.STATE_UNKNOWN, isEnabled, isMutable, priority,
|
||||||
overlayCategory));
|
overlayCategory, false /* hasConfiguratorActorPolicy */));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,6 +160,26 @@ final class OverlayManagerSettings {
|
|||||||
return mItems.get(idx).setState(state);
|
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,
|
List<OverlayInfo> getOverlaysForTarget(@NonNull final String targetPackageName,
|
||||||
final int userId) {
|
final int userId) {
|
||||||
// Immutable RROs targeting "android" are loaded from AssetManager, and so they should be
|
// Immutable RROs targeting "android" are loaded from AssetManager, and so they should be
|
||||||
@@ -323,16 +343,17 @@ final class OverlayManagerSettings {
|
|||||||
pw.println(item.mPackageName + ":" + item.getUserId() + " {");
|
pw.println(item.mPackageName + ":" + item.getUserId() + " {");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
|
|
||||||
pw.println("mPackageName...........: " + item.mPackageName);
|
pw.println("mPackageName................: " + item.mPackageName);
|
||||||
pw.println("mUserId................: " + item.getUserId());
|
pw.println("mUserId.....................: " + item.getUserId());
|
||||||
pw.println("mTargetPackageName.....: " + item.getTargetPackageName());
|
pw.println("mTargetPackageName..........: " + item.getTargetPackageName());
|
||||||
pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName());
|
pw.println("mTargetOverlayableName......: " + item.getTargetOverlayableName());
|
||||||
pw.println("mBaseCodePath..........: " + item.getBaseCodePath());
|
pw.println("mBaseCodePath...............: " + item.getBaseCodePath());
|
||||||
pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
|
pw.println("mState......................: " + OverlayInfo.stateToString(item.getState()));
|
||||||
pw.println("mIsEnabled.............: " + item.isEnabled());
|
pw.println("mIsEnabled..................: " + item.isEnabled());
|
||||||
pw.println("mIsMutable.............: " + item.isMutable());
|
pw.println("mIsMutable..................: " + item.isMutable());
|
||||||
pw.println("mPriority..............: " + item.mPriority);
|
pw.println("mPriority...................: " + item.mPriority);
|
||||||
pw.println("mCategory..............: " + item.mCategory);
|
pw.println("mCategory...................: " + item.mCategory);
|
||||||
|
pw.println("mHasConfiguratorActorPolicy.: " + item.hasConfiguratorActorPolicy());
|
||||||
|
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.println("}");
|
pw.println("}");
|
||||||
@@ -371,6 +392,9 @@ final class OverlayManagerSettings {
|
|||||||
case "category":
|
case "category":
|
||||||
pw.println(item.mCategory);
|
pw.println(item.mCategory);
|
||||||
break;
|
break;
|
||||||
|
case "hasconfiguratoractorpolicy":
|
||||||
|
pw.println(item.mHasConfiguratorActorPolicy);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,9 +422,11 @@ final class OverlayManagerSettings {
|
|||||||
private static final String ATTR_CATEGORY = "category";
|
private static final String ATTR_CATEGORY = "category";
|
||||||
private static final String ATTR_USER_ID = "userId";
|
private static final String ATTR_USER_ID = "userId";
|
||||||
private static final String ATTR_VERSION = "version";
|
private static final String ATTR_VERSION = "version";
|
||||||
|
private static final String ATTR_HAS_CONFIGURATOR_ACTOR_POLICY =
|
||||||
|
"hasConfiguratorActorPolicy";
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int CURRENT_VERSION = 3;
|
static final int CURRENT_VERSION = 4;
|
||||||
|
|
||||||
public static void restore(@NonNull final ArrayList<SettingsItem> table,
|
public static void restore(@NonNull final ArrayList<SettingsItem> table,
|
||||||
@NonNull final InputStream is) throws IOException, XmlPullParserException {
|
@NonNull final InputStream is) throws IOException, XmlPullParserException {
|
||||||
@@ -454,9 +480,12 @@ final class OverlayManagerSettings {
|
|||||||
final boolean isStatic = XmlUtils.readBooleanAttribute(parser, ATTR_IS_STATIC);
|
final boolean isStatic = XmlUtils.readBooleanAttribute(parser, ATTR_IS_STATIC);
|
||||||
final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY);
|
final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY);
|
||||||
final String category = XmlUtils.readStringAttribute(parser, ATTR_CATEGORY);
|
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,
|
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,
|
public static void persist(@NonNull final ArrayList<SettingsItem> table,
|
||||||
@@ -491,6 +520,8 @@ final class OverlayManagerSettings {
|
|||||||
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_STATIC, !item.mIsMutable);
|
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_STATIC, !item.mIsMutable);
|
||||||
XmlUtils.writeIntAttribute(xml, ATTR_PRIORITY, item.mPriority);
|
XmlUtils.writeIntAttribute(xml, ATTR_PRIORITY, item.mPriority);
|
||||||
XmlUtils.writeStringAttribute(xml, ATTR_CATEGORY, item.mCategory);
|
XmlUtils.writeStringAttribute(xml, ATTR_CATEGORY, item.mCategory);
|
||||||
|
XmlUtils.writeBooleanAttribute(xml, ATTR_HAS_CONFIGURATOR_ACTOR_POLICY,
|
||||||
|
item.mHasConfiguratorActorPolicy);
|
||||||
xml.endTag(null, TAG_ITEM);
|
xml.endTag(null, TAG_ITEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,12 +538,14 @@ final class OverlayManagerSettings {
|
|||||||
private boolean mIsMutable;
|
private boolean mIsMutable;
|
||||||
private int mPriority;
|
private int mPriority;
|
||||||
private String mCategory;
|
private String mCategory;
|
||||||
|
private boolean mHasConfiguratorActorPolicy;
|
||||||
|
|
||||||
SettingsItem(@NonNull final String packageName, final int userId,
|
SettingsItem(@NonNull final String packageName, final int userId,
|
||||||
@NonNull final String targetPackageName,
|
@NonNull final String targetPackageName,
|
||||||
@Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
|
@Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
|
||||||
final @OverlayInfo.State int state, final boolean isEnabled,
|
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;
|
mPackageName = packageName;
|
||||||
mUserId = userId;
|
mUserId = userId;
|
||||||
mTargetPackageName = targetPackageName;
|
mTargetPackageName = targetPackageName;
|
||||||
@@ -524,6 +557,7 @@ final class OverlayManagerSettings {
|
|||||||
mCache = null;
|
mCache = null;
|
||||||
mIsMutable = isMutable;
|
mIsMutable = isMutable;
|
||||||
mPriority = priority;
|
mPriority = priority;
|
||||||
|
mHasConfiguratorActorPolicy = hasConfiguratorActorPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTargetPackageName() {
|
private String getTargetPackageName() {
|
||||||
@@ -614,6 +648,18 @@ final class OverlayManagerSettings {
|
|||||||
private int getPriority() {
|
private int getPriority() {
|
||||||
return mPriority;
|
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) {
|
private int select(@NonNull final String packageName, final int userId) {
|
||||||
|
|||||||
@@ -80,24 +80,4 @@ public interface OverlayableInfoCallback {
|
|||||||
* in the system returns {@link PackageManager#SIGNATURE_MATCH}
|
* in the system returns {@link PackageManager#SIGNATURE_MATCH}
|
||||||
*/
|
*/
|
||||||
boolean signaturesMatching(@NonNull String pkgName1, @NonNull String pkgName2, int userId);
|
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,45 +208,134 @@ public class OverlayManagerServiceImplTests extends OverlayManagerServiceImplTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConfigurator() {
|
public void testConfigurator() {
|
||||||
final DummyPackageManagerHelper packageManager = getPackageManager();
|
mOverlayableConfigurator = "actor";
|
||||||
packageManager.overlayableConfigurator = "actor";
|
mOverlayableConfiguratorTargets = new String[]{TARGET};
|
||||||
packageManager.overlayableConfiguratorTargets = new String[]{TARGET};
|
|
||||||
reinitializeImpl();
|
reinitializeImpl();
|
||||||
|
|
||||||
installNewPackage(target("actor").setCertificate("one"), USER);
|
installNewPackage(target("actor").setCertificate("one"), USER);
|
||||||
installNewPackage(target(TARGET)
|
installNewPackage(target(TARGET).addOverlayable("TestResources").setCertificate("two"),
|
||||||
.addOverlayable("TestResources")
|
USER);
|
||||||
.setCertificate("two"), USER);
|
|
||||||
|
|
||||||
final DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
|
DummyDeviceState.PackageBuilder overlay = overlay(OVERLAY, TARGET, "TestResources")
|
||||||
.setCertificate("one");
|
.setCertificate("one");
|
||||||
installNewPackage(overlay, USER);
|
installNewPackage(overlay, USER);
|
||||||
|
|
||||||
final DummyIdmapDaemon idmapDaemon = getIdmapDaemon();
|
DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
|
||||||
final DummyIdmapDaemon.IdmapHeader idmap = idmapDaemon.getIdmap(overlay.build().apkPath);
|
|
||||||
assertNotNull(idmap);
|
assertNotNull(idmap);
|
||||||
assertEquals(OverlayablePolicy.ACTOR_SIGNATURE,
|
assertEquals(OverlayablePolicy.ACTOR_SIGNATURE,
|
||||||
idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
|
idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConfiguratorDifferentSignatures() {
|
public void testConfiguratorWithoutOverlayable() {
|
||||||
final DummyPackageManagerHelper packageManager = getPackageManager();
|
mOverlayableConfigurator = "actor";
|
||||||
packageManager.overlayableConfigurator = "actor";
|
mOverlayableConfiguratorTargets = new String[]{TARGET};
|
||||||
packageManager.overlayableConfiguratorTargets = new String[]{TARGET};
|
|
||||||
reinitializeImpl();
|
reinitializeImpl();
|
||||||
|
|
||||||
installNewPackage(target("actor").setCertificate("one"), USER);
|
installNewPackage(target("actor").setCertificate("one"), USER);
|
||||||
installNewPackage(target(TARGET)
|
installNewPackage(target(TARGET).setCertificate("two"), USER);
|
||||||
.addOverlayable("TestResources")
|
|
||||||
.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");
|
.setCertificate("two");
|
||||||
installNewPackage(overlay, USER);
|
installNewPackage(overlay, USER);
|
||||||
|
|
||||||
final DummyIdmapDaemon idmapDaemon = getIdmapDaemon();
|
DummyIdmapDaemon.IdmapHeader idmap = getIdmapDaemon().getIdmap(overlay.build().apkPath);
|
||||||
final DummyIdmapDaemon.IdmapHeader idmap = idmapDaemon.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);
|
assertNotNull(idmap);
|
||||||
assertEquals(0, idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
|
assertEquals(0, idmap.policies & OverlayablePolicy.ACTOR_SIGNATURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/** Base class for creating {@link OverlayManagerServiceImplTests} tests. */
|
/** Base class for creating {@link OverlayManagerServiceImplTests} tests. */
|
||||||
@@ -53,6 +52,9 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
private DummyPackageManagerHelper mPackageManager;
|
private DummyPackageManagerHelper mPackageManager;
|
||||||
private DummyIdmapDaemon mIdmapDaemon;
|
private DummyIdmapDaemon mIdmapDaemon;
|
||||||
private OverlayConfig mOverlayConfig;
|
private OverlayConfig mOverlayConfig;
|
||||||
|
private OverlayManagerSettings mSettings;
|
||||||
|
String mOverlayableConfigurator;
|
||||||
|
String[] mOverlayableConfiguratorTargets;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -60,20 +62,26 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
mListener = new DummyListener();
|
mListener = new DummyListener();
|
||||||
mPackageManager = new DummyPackageManagerHelper(mState);
|
mPackageManager = new DummyPackageManagerHelper(mState);
|
||||||
mIdmapDaemon = new DummyIdmapDaemon(mState);
|
mIdmapDaemon = new DummyIdmapDaemon(mState);
|
||||||
|
mSettings = new OverlayManagerSettings();
|
||||||
mOverlayConfig = mock(OverlayConfig.class);
|
mOverlayConfig = mock(OverlayConfig.class);
|
||||||
when(mOverlayConfig.getPriority(any())).thenReturn(OverlayConfig.DEFAULT_PRIORITY);
|
when(mOverlayConfig.getPriority(any())).thenReturn(OverlayConfig.DEFAULT_PRIORITY);
|
||||||
when(mOverlayConfig.isEnabled(any())).thenReturn(false);
|
when(mOverlayConfig.isEnabled(any())).thenReturn(false);
|
||||||
when(mOverlayConfig.isMutable(any())).thenReturn(true);
|
when(mOverlayConfig.isMutable(any())).thenReturn(true);
|
||||||
|
mOverlayableConfigurator = null;
|
||||||
|
mOverlayableConfiguratorTargets = null;
|
||||||
reinitializeImpl();
|
reinitializeImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reinitializeImpl() {
|
OverlayManagerServiceImpl reinitializeImpl() {
|
||||||
mImpl = new OverlayManagerServiceImpl(mPackageManager,
|
mImpl = new OverlayManagerServiceImpl(mPackageManager,
|
||||||
new IdmapManager(mIdmapDaemon, mPackageManager),
|
new IdmapManager(mIdmapDaemon, mPackageManager),
|
||||||
new OverlayManagerSettings(),
|
mSettings,
|
||||||
mOverlayConfig,
|
mOverlayConfig,
|
||||||
new String[0],
|
new String[0],
|
||||||
mListener);
|
mListener,
|
||||||
|
mOverlayableConfigurator,
|
||||||
|
mOverlayableConfiguratorTargets);
|
||||||
|
return mImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayManagerServiceImpl getImpl() {
|
OverlayManagerServiceImpl getImpl() {
|
||||||
@@ -84,14 +92,14 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
return mListener;
|
return mListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
DummyPackageManagerHelper getPackageManager() {
|
|
||||||
return mPackageManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
DummyIdmapDaemon getIdmapDaemon() {
|
DummyIdmapDaemon getIdmapDaemon() {
|
||||||
return mIdmapDaemon;
|
return mIdmapDaemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OverlayManagerSettings getSettings() {
|
||||||
|
return mSettings;
|
||||||
|
}
|
||||||
|
|
||||||
void assertState(@State int expected, final String overlayPackageName, int userId) {
|
void assertState(@State int expected, final String overlayPackageName, int userId) {
|
||||||
final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
|
final OverlayInfo info = mImpl.getOverlayInfo(overlayPackageName, userId);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
@@ -314,8 +322,6 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
static final class DummyPackageManagerHelper implements PackageManagerHelper,
|
static final class DummyPackageManagerHelper implements PackageManagerHelper,
|
||||||
OverlayableInfoCallback {
|
OverlayableInfoCallback {
|
||||||
private final DummyDeviceState mState;
|
private final DummyDeviceState mState;
|
||||||
String[] overlayableConfiguratorTargets = new String[0];
|
|
||||||
String overlayableConfigurator = "";
|
|
||||||
|
|
||||||
private DummyPackageManagerHelper(DummyDeviceState state) {
|
private DummyPackageManagerHelper(DummyDeviceState state) {
|
||||||
mState = state;
|
mState = state;
|
||||||
@@ -387,16 +393,6 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
public void enforcePermission(String permission, String message) throws SecurityException {
|
public void enforcePermission(String permission, String message) throws SecurityException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getOverlayableConfiguratorTargets() {
|
|
||||||
return overlayableConfiguratorTargets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getOverlayableConfigurator() {
|
|
||||||
return overlayableConfigurator;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DummyIdmapDaemon extends IdmapDaemon {
|
static class DummyIdmapDaemon extends IdmapDaemon {
|
||||||
@@ -433,7 +429,8 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
if (idmap == null) {
|
if (idmap == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return idmap.isUpToDate(getCrc(targetPath), getCrc(overlayPath), targetPath);
|
return idmap.isUpToDate(getCrc(targetPath), getCrc(overlayPath), targetPath, policies,
|
||||||
|
enforce);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -462,9 +459,11 @@ class OverlayManagerServiceImplTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isUpToDate(int expectedTargetCrc, int expectedOverlayCrc,
|
private boolean isUpToDate(int expectedTargetCrc, int expectedOverlayCrc,
|
||||||
String expectedTargetPath) {
|
String expectedTargetPath, int expectedPolicies,
|
||||||
|
boolean expectedEnforceOverlayable) {
|
||||||
return expectedTargetCrc == targetCrc && expectedOverlayCrc == overlayCrc
|
return expectedTargetCrc == targetCrc && expectedOverlayCrc == overlayCrc
|
||||||
&& expectedTargetPath.equals(targetPath);
|
&& expectedTargetPath.equals(targetPath) && expectedPolicies == policies
|
||||||
|
&& expectedEnforceOverlayable == enforceOverlayable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,7 +367,8 @@ public class OverlayManagerSettingsTests {
|
|||||||
+ " isEnabled='false'\n"
|
+ " isEnabled='false'\n"
|
||||||
+ " category='dummy-category'\n"
|
+ " category='dummy-category'\n"
|
||||||
+ " isStatic='false'\n"
|
+ " isStatic='false'\n"
|
||||||
+ " priority='0' />\n"
|
+ " priority='0'"
|
||||||
|
+ " hasConfiguratorActorPolicy='true' />\n"
|
||||||
+ "</overlays>\n";
|
+ "</overlays>\n";
|
||||||
ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes("utf-8"));
|
ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes("utf-8"));
|
||||||
|
|
||||||
@@ -380,6 +381,7 @@ public class OverlayManagerSettingsTests {
|
|||||||
assertEquals(1234, oi.userId);
|
assertEquals(1234, oi.userId);
|
||||||
assertEquals(STATE_DISABLED, oi.state);
|
assertEquals(STATE_DISABLED, oi.state);
|
||||||
assertFalse(mSettings.getEnabled("com.dummy.overlay", 1234));
|
assertFalse(mSettings.getEnabled("com.dummy.overlay", 1234));
|
||||||
|
assertTrue(mSettings.hasConfiguratorActorPolicy("com.dummy.overlay", 1234));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user