OverlayManager: Add categories
Adds the possibility to declare different categories for resource overlays (e.g. themes, display cutout emulation, ...) Bug: 72436677 Test: adb shell cmd overlay enable-exclusive --category com.android.internal.display_cutout_emulation android com.android.internal.display.cutout.emulation.narrow Test: adb shell cmd overlay enable-exclusive --category com.android.internal.display_cutout_emulation android Change-Id: I23f22113351b3948beb9e3a1fb969700852539cc
This commit is contained in:
@@ -83,16 +83,35 @@ interface IOverlayManager {
|
||||
* @param packageName The name of the overlay package.
|
||||
* @param enable true to enable the overlay, false to disable it.
|
||||
* @param userId The user for which to change the overlay.
|
||||
* @return true if the system successfully registered the request, false
|
||||
* otherwise.
|
||||
* @return true if the system successfully registered the request, false otherwise.
|
||||
*/
|
||||
boolean setEnabled(in String packageName, in boolean enable, in int userId);
|
||||
|
||||
/**
|
||||
* Version of setEnabled that will also disable any other overlays for the target package.
|
||||
* Request that an overlay package is enabled and any other overlay packages with the same
|
||||
* target package are disabled.
|
||||
*
|
||||
* See {@link #setEnabled} for the details on overlay packages.
|
||||
*
|
||||
* @param packageName the name of the overlay package to enable.
|
||||
* @param enabled must be true, otherwise the operation fails.
|
||||
* @param userId The user for which to change the overlay.
|
||||
* @return true if the system successfully registered the request, false otherwise.
|
||||
*/
|
||||
boolean setEnabledExclusive(in String packageName, in boolean enable, in int userId);
|
||||
|
||||
/**
|
||||
* Request that an overlay package is enabled and any other overlay packages with the same
|
||||
* target package and category are disabled.
|
||||
*
|
||||
* See {@link #setEnabled} for the details on overlay packages.
|
||||
*
|
||||
* @param packageName the name of the overlay package to enable.
|
||||
* @param userId The user for which to change the overlay.
|
||||
* @return true if the system successfully registered the request, false otherwise.
|
||||
*/
|
||||
boolean setEnabledExclusiveInCategory(in String packageName, in int userId);
|
||||
|
||||
/**
|
||||
* Change the priority of the given overlay to be just higher than the
|
||||
* overlay with package name newParentPackageName. Both overlay packages
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.content.om;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -66,14 +67,14 @@ public final class OverlayInfo implements Parcelable {
|
||||
/**
|
||||
* The overlay is currently disabled. It can be enabled.
|
||||
*
|
||||
* @see IOverlayManager.setEnabled
|
||||
* @see IOverlayManager#setEnabled
|
||||
*/
|
||||
public static final int STATE_DISABLED = 2;
|
||||
|
||||
/**
|
||||
* The overlay is currently enabled. It can be disabled.
|
||||
*
|
||||
* @see IOverlayManager.setEnabled
|
||||
* @see IOverlayManager#setEnabled
|
||||
*/
|
||||
public static final int STATE_ENABLED = 3;
|
||||
|
||||
@@ -89,6 +90,11 @@ public final class OverlayInfo implements Parcelable {
|
||||
*/
|
||||
public static final int STATE_OVERLAY_UPGRADING = 5;
|
||||
|
||||
/**
|
||||
* Category for theme overlays.
|
||||
*/
|
||||
public static final String CATEGORY_THEME = "android.theme";
|
||||
|
||||
/**
|
||||
* Package name of the overlay package
|
||||
*/
|
||||
@@ -99,6 +105,11 @@ public final class OverlayInfo implements Parcelable {
|
||||
*/
|
||||
public final String targetPackageName;
|
||||
|
||||
/**
|
||||
* Category of the overlay package
|
||||
*/
|
||||
public final String category;
|
||||
|
||||
/**
|
||||
* Full path to the base APK for this overlay package
|
||||
*/
|
||||
@@ -121,14 +132,15 @@ public final class OverlayInfo implements Parcelable {
|
||||
* @param state the new state for the source OverlayInfo
|
||||
*/
|
||||
public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
|
||||
this(source.packageName, source.targetPackageName, source.baseCodePath, state,
|
||||
source.userId);
|
||||
this(source.packageName, source.targetPackageName, source.category, source.baseCodePath,
|
||||
state, source.userId);
|
||||
}
|
||||
|
||||
public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
|
||||
@NonNull String baseCodePath, @State int state, int userId) {
|
||||
@Nullable String category, @NonNull String baseCodePath, int state, int userId) {
|
||||
this.packageName = packageName;
|
||||
this.targetPackageName = targetPackageName;
|
||||
this.category = category;
|
||||
this.baseCodePath = baseCodePath;
|
||||
this.state = state;
|
||||
this.userId = userId;
|
||||
@@ -138,6 +150,7 @@ public final class OverlayInfo implements Parcelable {
|
||||
public OverlayInfo(Parcel source) {
|
||||
packageName = source.readString();
|
||||
targetPackageName = source.readString();
|
||||
category = source.readString();
|
||||
baseCodePath = source.readString();
|
||||
state = source.readInt();
|
||||
userId = source.readInt();
|
||||
@@ -177,6 +190,7 @@ public final class OverlayInfo implements Parcelable {
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(packageName);
|
||||
dest.writeString(targetPackageName);
|
||||
dest.writeString(category);
|
||||
dest.writeString(baseCodePath);
|
||||
dest.writeInt(state);
|
||||
dest.writeInt(userId);
|
||||
@@ -275,6 +289,9 @@ public final class OverlayInfo implements Parcelable {
|
||||
if (!targetPackageName.equals(other.targetPackageName)) {
|
||||
return false;
|
||||
}
|
||||
if (!category.equals(other.category)) {
|
||||
return false;
|
||||
}
|
||||
if (!baseCodePath.equals(other.baseCodePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -362,6 +362,13 @@ public class PackageInfo implements Parcelable {
|
||||
*/
|
||||
public String overlayTarget;
|
||||
|
||||
/**
|
||||
* The overlay category, if any, of this package
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public String overlayCategory;
|
||||
|
||||
/** @hide */
|
||||
public int overlayPriority;
|
||||
|
||||
@@ -464,6 +471,7 @@ public class PackageInfo implements Parcelable {
|
||||
dest.writeString(restrictedAccountType);
|
||||
dest.writeString(requiredAccountType);
|
||||
dest.writeString(overlayTarget);
|
||||
dest.writeString(overlayCategory);
|
||||
dest.writeInt(overlayPriority);
|
||||
dest.writeBoolean(mOverlayIsStatic);
|
||||
dest.writeInt(compileSdkVersion);
|
||||
@@ -531,6 +539,7 @@ public class PackageInfo implements Parcelable {
|
||||
restrictedAccountType = source.readString();
|
||||
requiredAccountType = source.readString();
|
||||
overlayTarget = source.readString();
|
||||
overlayCategory = source.readString();
|
||||
overlayPriority = source.readInt();
|
||||
mOverlayIsStatic = source.readBoolean();
|
||||
compileSdkVersion = source.readInt();
|
||||
|
||||
@@ -676,6 +676,7 @@ public class PackageParser {
|
||||
pi.restrictedAccountType = p.mRestrictedAccountType;
|
||||
pi.requiredAccountType = p.mRequiredAccountType;
|
||||
pi.overlayTarget = p.mOverlayTarget;
|
||||
pi.overlayCategory = p.mOverlayCategory;
|
||||
pi.overlayPriority = p.mOverlayPriority;
|
||||
pi.mOverlayIsStatic = p.mOverlayIsStatic;
|
||||
pi.compileSdkVersion = p.mCompileSdkVersion;
|
||||
@@ -2073,6 +2074,8 @@ public class PackageParser {
|
||||
com.android.internal.R.styleable.AndroidManifestResourceOverlay);
|
||||
pkg.mOverlayTarget = sa.getString(
|
||||
com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
|
||||
pkg.mOverlayCategory = sa.getString(
|
||||
com.android.internal.R.styleable.AndroidManifestResourceOverlay_category);
|
||||
pkg.mOverlayPriority = sa.getInt(
|
||||
com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,
|
||||
0);
|
||||
@@ -6324,6 +6327,7 @@ public class PackageParser {
|
||||
public String mRequiredAccountType;
|
||||
|
||||
public String mOverlayTarget;
|
||||
public String mOverlayCategory;
|
||||
public int mOverlayPriority;
|
||||
public boolean mOverlayIsStatic;
|
||||
|
||||
@@ -6834,6 +6838,7 @@ public class PackageParser {
|
||||
mRestrictedAccountType = dest.readString();
|
||||
mRequiredAccountType = dest.readString();
|
||||
mOverlayTarget = dest.readString();
|
||||
mOverlayCategory = dest.readString();
|
||||
mOverlayPriority = dest.readInt();
|
||||
mOverlayIsStatic = (dest.readInt() == 1);
|
||||
mCompileSdkVersion = dest.readInt();
|
||||
@@ -6957,6 +6962,7 @@ public class PackageParser {
|
||||
dest.writeString(mRestrictedAccountType);
|
||||
dest.writeString(mRequiredAccountType);
|
||||
dest.writeString(mOverlayTarget);
|
||||
dest.writeString(mOverlayCategory);
|
||||
dest.writeInt(mOverlayPriority);
|
||||
dest.writeInt(mOverlayIsStatic ? 1 : 0);
|
||||
dest.writeInt(mCompileSdkVersion);
|
||||
|
||||
@@ -52,6 +52,16 @@ public final class DisplayCutout {
|
||||
private static final String TAG = "DisplayCutout";
|
||||
private static final String DP_MARKER = "@dp";
|
||||
|
||||
/**
|
||||
* Category for overlays that allow emulating a display cutout on devices that don't have
|
||||
* one.
|
||||
*
|
||||
* @see android.content.om.IOverlayManager
|
||||
* @hide
|
||||
*/
|
||||
public static final String EMULATION_OVERLAY_CATEGORY =
|
||||
"com.android.internal.display_cutout_emulation";
|
||||
|
||||
private static final Rect ZERO_RECT = new Rect();
|
||||
private static final Region EMPTY_REGION = new Region();
|
||||
|
||||
|
||||
@@ -2558,6 +2558,9 @@
|
||||
<!-- Package name of base package whose resources will be overlaid. -->
|
||||
<attr name="targetPackage" />
|
||||
|
||||
<!-- Category of the resource overlay. -->
|
||||
<attr name="category" format="string"/>
|
||||
|
||||
<!-- Load order of overlay package. -->
|
||||
<attr name="priority" />
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
package="com.android.internal.display.cutout.emulation.narrow"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<overlay android:targetPackage="android" android:priority="1"/>
|
||||
<overlay android:targetPackage="android"
|
||||
android:category="com.android.internal.display_cutout_emulation"
|
||||
android:priority="1"/>
|
||||
|
||||
<application android:label="@string/display_cutout_emulation_overlay" android:hasCode="false"/>
|
||||
</manifest>
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
package="com.android.internal.display.cutout.emulation.tall"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<overlay android:targetPackage="android" android:priority="1"/>
|
||||
<overlay android:targetPackage="android"
|
||||
android:category="com.android.internal.display_cutout_emulation"
|
||||
android:priority="1"/>
|
||||
|
||||
<application android:label="@string/display_cutout_emulation_overlay" android:hasCode="false"/>
|
||||
</manifest>
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
package="com.android.internal.display.cutout.emulation.wide"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<overlay android:targetPackage="android" android:priority="1"/>
|
||||
<overlay android:targetPackage="android"
|
||||
android:category="com.android.internal.display_cutout_emulation"
|
||||
android:priority="1"/>
|
||||
|
||||
<application android:label="@string/display_cutout_emulation_overlay" android:hasCode="false"/>
|
||||
</manifest>
|
||||
|
||||
@@ -544,7 +544,28 @@ public final class OverlayManagerService extends SystemService {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
return mImpl.setEnabledExclusive(packageName, userId);
|
||||
return mImpl.setEnabledExclusive(packageName, false /* withinCategory */,
|
||||
userId);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setEnabledExclusiveInCategory(@Nullable String packageName, int userId)
|
||||
throws RemoteException {
|
||||
enforceChangeOverlayPackagesPermission("setEnabled");
|
||||
userId = handleIncomingUser(userId, "setEnabled");
|
||||
if (packageName == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
return mImpl.setEnabledExclusive(packageName, true /* withinCategory */,
|
||||
userId);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
|
||||
@@ -35,6 +35,8 @@ import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
|
||||
import libcore.util.Objects;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -103,12 +105,14 @@ final class OverlayManagerServiceImpl {
|
||||
for (int i = 0; i < overlayPackagesSize; i++) {
|
||||
final PackageInfo overlayPackage = overlayPackages.get(i);
|
||||
final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
|
||||
if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
|
||||
if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)
|
||||
|| !Objects.equal(oi.category, overlayPackage.overlayCategory)) {
|
||||
// Update the overlay if it didn't exist or had the wrong target package.
|
||||
mSettings.init(overlayPackage.packageName, newUserId,
|
||||
overlayPackage.overlayTarget,
|
||||
overlayPackage.applicationInfo.getBaseCodePath(),
|
||||
overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority);
|
||||
overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
|
||||
overlayPackage.overlayCategory);
|
||||
|
||||
if (oi == null) {
|
||||
// This overlay does not exist in our settings.
|
||||
@@ -259,7 +263,8 @@ final class OverlayManagerServiceImpl {
|
||||
|
||||
mSettings.init(packageName, userId, overlayPackage.overlayTarget,
|
||||
overlayPackage.applicationInfo.getBaseCodePath(),
|
||||
overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority);
|
||||
overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
|
||||
overlayPackage.overlayCategory);
|
||||
try {
|
||||
if (updateState(overlayPackage.overlayTarget, packageName, userId, 0)) {
|
||||
mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
|
||||
@@ -320,7 +325,7 @@ final class OverlayManagerServiceImpl {
|
||||
if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) {
|
||||
mSettings.init(packageName, userId, pkg.overlayTarget,
|
||||
pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
|
||||
pkg.overlayPriority);
|
||||
pkg.overlayPriority, pkg.overlayCategory);
|
||||
}
|
||||
|
||||
if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
|
||||
@@ -394,10 +399,11 @@ final class OverlayManagerServiceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
boolean setEnabledExclusive(@NonNull final String packageName, final int userId) {
|
||||
boolean setEnabledExclusive(@NonNull final String packageName, boolean withinCategory,
|
||||
final int userId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, String.format("setEnabledExclusive packageName=%s userId=%d", packageName,
|
||||
userId));
|
||||
Slog.d(TAG, String.format("setEnabledExclusive packageName=%s"
|
||||
+ " withinCategory=%s userId=%d", packageName, withinCategory, userId));
|
||||
}
|
||||
|
||||
final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
|
||||
@@ -428,6 +434,11 @@ final class OverlayManagerServiceImpl {
|
||||
// Don't touch static overlays.
|
||||
continue;
|
||||
}
|
||||
if (withinCategory && !Objects.equal(disabledOverlayPackageInfo.overlayCategory,
|
||||
oi.category)) {
|
||||
// Don't touch overlays from other categories.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Disable the overlay.
|
||||
modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false);
|
||||
|
||||
@@ -20,10 +20,7 @@ import static com.android.server.om.OverlayManagerService.DEBUG;
|
||||
import static com.android.server.om.OverlayManagerService.TAG;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.om.OverlayInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
@@ -67,11 +64,11 @@ final class OverlayManagerSettings {
|
||||
|
||||
void init(@NonNull final String packageName, final int userId,
|
||||
@NonNull final String targetPackageName, @NonNull final String baseCodePath,
|
||||
boolean isStatic, int priority) {
|
||||
boolean isStatic, int priority, String overlayCategory) {
|
||||
remove(packageName, userId);
|
||||
final SettingsItem item =
|
||||
new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
|
||||
isStatic, priority);
|
||||
isStatic, priority, overlayCategory);
|
||||
if (isStatic) {
|
||||
int i;
|
||||
for (i = mItems.size() - 1; i >= 0; i--) {
|
||||
@@ -292,6 +289,7 @@ final class OverlayManagerSettings {
|
||||
pw.print("mState.............: "); pw.println(OverlayInfo.stateToString(item.getState()));
|
||||
pw.print("mIsEnabled.........: "); pw.println(item.isEnabled());
|
||||
pw.print("mIsStatic..........: "); pw.println(item.isStatic());
|
||||
pw.print("mCategory..........: "); pw.println(item.mCategory);
|
||||
|
||||
pw.decreaseIndent();
|
||||
pw.println("}");
|
||||
@@ -317,6 +315,7 @@ final class OverlayManagerSettings {
|
||||
private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName";
|
||||
private static final String ATTR_IS_STATIC = "isStatic";
|
||||
private static final String ATTR_PRIORITY = "priority";
|
||||
private static final String ATTR_CATEGORY = "category";
|
||||
private static final String ATTR_USER_ID = "userId";
|
||||
private static final String ATTR_VERSION = "version";
|
||||
|
||||
@@ -371,9 +370,10 @@ final class OverlayManagerSettings {
|
||||
final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED);
|
||||
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);
|
||||
|
||||
return new SettingsItem(packageName, userId, targetPackageName, baseCodePath, state,
|
||||
isEnabled, isStatic, priority);
|
||||
return new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
|
||||
state, isEnabled, isStatic, priority, category);
|
||||
}
|
||||
|
||||
public static void persist(@NonNull final ArrayList<SettingsItem> table,
|
||||
@@ -405,6 +405,7 @@ final class OverlayManagerSettings {
|
||||
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.mIsEnabled);
|
||||
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_STATIC, item.mIsStatic);
|
||||
XmlUtils.writeIntAttribute(xml, ATTR_PRIORITY, item.mPriority);
|
||||
XmlUtils.writeStringAttribute(xml, ATTR_CATEGORY, item.mCategory);
|
||||
xml.endTag(null, TAG_ITEM);
|
||||
}
|
||||
}
|
||||
@@ -419,17 +420,19 @@ final class OverlayManagerSettings {
|
||||
private OverlayInfo mCache;
|
||||
private boolean mIsStatic;
|
||||
private int mPriority;
|
||||
private final String mCategory;
|
||||
|
||||
SettingsItem(@NonNull final String packageName, final int userId,
|
||||
@NonNull final String targetPackageName, @NonNull final String baseCodePath,
|
||||
final @OverlayInfo.State int state, final boolean isEnabled, final boolean isStatic,
|
||||
final int priority) {
|
||||
final int priority, String category) {
|
||||
mPackageName = packageName;
|
||||
mUserId = userId;
|
||||
mTargetPackageName = targetPackageName;
|
||||
mBaseCodePath = baseCodePath;
|
||||
mState = state;
|
||||
mIsEnabled = isEnabled;
|
||||
mCategory = category;
|
||||
mCache = null;
|
||||
mIsStatic = isStatic;
|
||||
mPriority = priority;
|
||||
@@ -437,9 +440,9 @@ final class OverlayManagerSettings {
|
||||
|
||||
SettingsItem(@NonNull final String packageName, final int userId,
|
||||
@NonNull final String targetPackageName, @NonNull final String baseCodePath,
|
||||
final boolean isStatic, final int priority) {
|
||||
final boolean isStatic, final int priority, String category) {
|
||||
this(packageName, userId, targetPackageName, baseCodePath, OverlayInfo.STATE_UNKNOWN,
|
||||
false, isStatic, priority);
|
||||
false, isStatic, priority, category);
|
||||
}
|
||||
|
||||
private String getTargetPackageName() {
|
||||
@@ -491,8 +494,8 @@ final class OverlayManagerSettings {
|
||||
|
||||
private OverlayInfo getOverlayInfo() {
|
||||
if (mCache == null) {
|
||||
mCache = new OverlayInfo(mPackageName, mTargetPackageName, mBaseCodePath, mState,
|
||||
mUserId);
|
||||
mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
|
||||
mState, mUserId);
|
||||
}
|
||||
return mCache;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ final class OverlayManagerShellCommand extends ShellCommand {
|
||||
return runEnableDisable(true);
|
||||
case "disable":
|
||||
return runEnableDisable(false);
|
||||
case "enable-exclusive":
|
||||
return runEnableExclusive();
|
||||
case "set-priority":
|
||||
return runSetPriority();
|
||||
default:
|
||||
@@ -86,6 +88,10 @@ final class OverlayManagerShellCommand extends ShellCommand {
|
||||
out.println(" Enable overlay package PACKAGE.");
|
||||
out.println(" disable [--user USER_ID] PACKAGE");
|
||||
out.println(" Disable overlay package PACKAGE.");
|
||||
out.println(" enable-exclusive [--user USER_ID] [--category] PACKAGE");
|
||||
out.println(" Enable overlay package PACKAGE and disable all other overlays for");
|
||||
out.println(" its target package. If the --category option is given, only disables");
|
||||
out.println(" other overlays in the same category.");
|
||||
out.println(" set-priority [--user USER_ID] PACKAGE PARENT|lowest|highest");
|
||||
out.println(" Change the priority of the overlay PACKAGE to be just higher than");
|
||||
out.println(" the priority of PACKAGE_PARENT If PARENT is the special keyword");
|
||||
@@ -157,6 +163,33 @@ final class OverlayManagerShellCommand extends ShellCommand {
|
||||
return mInterface.setEnabled(packageName, enable, userId) ? 0 : 1;
|
||||
}
|
||||
|
||||
private int runEnableExclusive() throws RemoteException {
|
||||
final PrintWriter err = getErrPrintWriter();
|
||||
|
||||
int userId = UserHandle.USER_SYSTEM;
|
||||
boolean inCategory = false;
|
||||
String opt;
|
||||
while ((opt = getNextOption()) != null) {
|
||||
switch (opt) {
|
||||
case "--user":
|
||||
userId = UserHandle.parseUserArg(getNextArgRequired());
|
||||
break;
|
||||
case "--category":
|
||||
inCategory = true;
|
||||
break;
|
||||
default:
|
||||
err.println("Error: Unknown option: " + opt);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
final String overlay = getNextArgRequired();
|
||||
if (inCategory) {
|
||||
return mInterface.setEnabledExclusiveInCategory(overlay, userId) ? 0 : 1;
|
||||
} else {
|
||||
return mInterface.setEnabledExclusive(overlay, true, userId) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
private int runSetPriority() throws RemoteException {
|
||||
final PrintWriter err = getErrPrintWriter();
|
||||
|
||||
|
||||
@@ -4637,6 +4637,11 @@ public final class Settings {
|
||||
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
|
||||
pw.println();
|
||||
|
||||
if (ps.pkg.mOverlayTarget != null) {
|
||||
pw.print(prefix); pw.print(" overlayTarget="); pw.println(ps.pkg.mOverlayTarget);
|
||||
pw.print(prefix); pw.print(" overlayCategory="); pw.println(ps.pkg.mOverlayCategory);
|
||||
}
|
||||
|
||||
if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
|
||||
final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
|
||||
pw.print(prefix); pw.println(" declared permissions:");
|
||||
|
||||
Reference in New Issue
Block a user