summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/Intent.java34
-rw-r--r--core/java/android/content/om/IOverlayManager.aidl129
-rw-r--r--core/java/android/content/om/OverlayInfo.aidl19
-rw-r--r--core/java/android/content/om/OverlayInfo.java263
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java29
6 files changed, 484 insertions, 0 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c7c680f06613..f610a292dcd3 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3754,6 +3754,16 @@ public abstract class Context {
public static final String INCIDENT_SERVICE = "incident";
/**
+ * Use with {@link #getSystemService} to retrieve a {@link
+ * android.content.om.OverlayManager} for managing overlay packages.
+ *
+ * @see #getSystemService
+ * @see android.content.om.OverlayManager
+ * @hide
+ */
+ public static final String OVERLAY_SERVICE = "overlay";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 249001befd82..111b4d6efa6e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3133,6 +3133,40 @@ public class Intent implements Parcelable, Cloneable {
"android.intent.action.MEDIA_RESOURCE_GRANTED";
/**
+ * Broadcast Action: An overlay package has been installed. The data
+ * contains the name of the added overlay package.
+ * @hide
+ */
+ public static final String ACTION_OVERLAY_ADDED = "android.intent.action.OVERLAY_ADDED";
+
+ /**
+ * Broadcast Action: An overlay package has changed. The data contains the
+ * name of the overlay package which has changed. This is broadcast on all
+ * changes to the OverlayInfo returned by {@link
+ * android.content.om.IOverlayManager#getOverlayInfo(String, int)}. The
+ * most common change is a state change that will change whether the
+ * overlay is enabled or not.
+ * @hide
+ */
+ public static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+
+ /**
+ * Broadcast Action: An overlay package has been removed. The data contains
+ * the name of the overlay package which has been removed.
+ * @hide
+ */
+ public static final String ACTION_OVERLAY_REMOVED = "android.intent.action.OVERLAY_REMOVED";
+
+ /**
+ * Broadcast Action: The order of a package's list of overlay packages has
+ * changed. The data contains the package name of the overlay package that
+ * had its position in the list adjusted.
+ * @hide
+ */
+ public static final String
+ ACTION_OVERLAY_PRIORITY_CHANGED = "android.intent.action.OVERLAY_PRIORITY_CHANGED";
+
+ /**
* Activity Action: Allow the user to select and return one or more existing
* documents. When invoked, the system will display the various
* {@link DocumentsProvider} instances installed on the device, letting the
diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl
new file mode 100644
index 000000000000..4f5d96038d1e
--- /dev/null
+++ b/core/java/android/content/om/IOverlayManager.aidl
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.om;
+
+import android.content.om.OverlayInfo;
+
+/**
+ * Api for getting information about overlay packages.
+ *
+ * {@hide}
+ */
+interface IOverlayManager {
+ /**
+ * Returns information about all installed overlay packages for the
+ * specified user. If there are no installed overlay packages for this user,
+ * an empty map is returned (i.e. null is never returned). The returned map is a
+ * mapping of target package names to lists of overlays. Each list for a
+ * given target package is sorted in priority order, with the overlay with
+ * the highest priority at the end of the list.
+ *
+ * @param userId The user to get the OverlayInfos for.
+ * @return A Map<String, List<OverlayInfo>> with target package names
+ * mapped to lists of overlays; if no overlays exist for the
+ * requested user, an empty map is returned.
+ */
+ Map getAllOverlays(in int userId);
+
+ /**
+ * Returns information about all overlays for the given target package for
+ * the specified user. The returned list is ordered according to the
+ * overlay priority with the highest priority at the end of the list.
+ *
+ * @param targetPackageName The name of the target package.
+ * @param userId The user to get the OverlayInfos for.
+ * @return A list of OverlayInfo objects; if no overlays exist for the
+ * requested package, an empty list is returned.
+ */
+ List getOverlayInfosForTarget(in String targetPackageName, in int userId);
+
+ /**
+ * Returns information about the overlay with the given package name for the
+ * specified user.
+ *
+ * @param packageName The name of the overlay package.
+ * @param userId The user to get the OverlayInfo for.
+ * @return The OverlayInfo for the overlay package; or null if no such
+ * overlay package exists.
+ */
+ OverlayInfo getOverlayInfo(in String packageName, in int userId);
+
+ /**
+ * Request that an overlay package be enabled or disabled when possible to
+ * do so.
+ *
+ * It is always possible to disable an overlay, but due to technical and
+ * security reasons it may not always be possible to enable an overlay. An
+ * example of the latter is when the related target package is not
+ * installed. If the technical obstacle is later overcome, the overlay is
+ * automatically enabled at that point in time.
+ *
+ * An enabled overlay is a part of target package's resources, i.e. it will
+ * be part of any lookups performed via {@link android.content.res.Resources}
+ * and {@link android.content.res.AssetManager}. A disabled overlay will no
+ * longer affect the resources of the target package. If the target is
+ * currently running, its outdated resources will be replaced by new ones.
+ * This happens the same way as when an application enters or exits split
+ * window mode.
+ *
+ * @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.
+ */
+ boolean setEnabled(in String packageName, in boolean enable, in int userId);
+
+ /**
+ * Change the priority of the given overlay to be just higher than the
+ * overlay with package name newParentPackageName. Both overlay packages
+ * must have the same target and user.
+ *
+ * @see getOverlayInfosForTarget
+ *
+ * @param packageName The name of the overlay package whose priority should
+ * be adjusted.
+ * @param newParentPackageName The name of the overlay package the newly
+ * adjusted overlay package should just outrank.
+ * @param userId The user for which to change the overlay.
+ */
+ boolean setPriority(in String packageName, in String newParentPackageName, in int userId);
+
+ /**
+ * Change the priority of the given overlay to the highest priority relative to
+ * the other overlays with the same target and user.
+ *
+ * @see getOverlayInfosForTarget
+ *
+ * @param packageName The name of the overlay package whose priority should
+ * be adjusted.
+ * @param userId The user for which to change the overlay.
+ */
+ boolean setHighestPriority(in String packageName, in int userId);
+
+ /**
+ * Change the priority of the overlay to the lowest priority relative to
+ * the other overlays for the same target and user.
+ *
+ * @see getOverlayInfosForTarget
+ *
+ * @param packageName The name of the overlay package whose priority should
+ * be adjusted.
+ * @param userId The user for which to change the overlay.
+ */
+ boolean setLowestPriority(in String packageName, in int userId);
+}
diff --git a/core/java/android/content/om/OverlayInfo.aidl b/core/java/android/content/om/OverlayInfo.aidl
new file mode 100644
index 000000000000..e7d413d07756
--- /dev/null
+++ b/core/java/android/content/om/OverlayInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.om;
+
+parcelable OverlayInfo;
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
new file mode 100644
index 000000000000..1a207ba055fc
--- /dev/null
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.om;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Immutable overlay information about a package. All PackageInfos that
+ * represent an overlay package will have a corresponding OverlayInfo.
+ *
+ * @hide
+ */
+public final class OverlayInfo implements Parcelable {
+ /**
+ * An internal state used as the initial state of an overlay. OverlayInfo
+ * objects exposed outside the {@link
+ * com.android.server.om.OverlayManagerService} should never have this
+ * state.
+ */
+ public static final int STATE_UNKNOWN = -1;
+
+ /**
+ * The target package of the overlay is not installed. The overlay cannot be enabled.
+ */
+ public static final int STATE_MISSING_TARGET = 0;
+
+ /**
+ * Creation of idmap file failed (e.g. no matching resources). The overlay
+ * cannot be enabled.
+ */
+ public static final int STATE_NO_IDMAP = 1;
+
+ /**
+ * The overlay is currently disabled. It can be enabled.
+ *
+ * @see IOverlayManager.setEnabled
+ */
+ public static final int STATE_DISABLED = 2;
+
+ /**
+ * The overlay is currently enabled. It can be disabled.
+ *
+ * @see IOverlayManager.setEnabled
+ */
+ public static final int STATE_ENABLED = 3;
+
+ /**
+ * Package name of the overlay package
+ */
+ public final String packageName;
+
+ /**
+ * Package name of the target package
+ */
+ public final String targetPackageName;
+
+ /**
+ * Full path to the base APK for this overlay package
+ */
+ public final String baseCodePath;
+
+ /**
+ * The state of this OverlayInfo as defined by the STATE_* constants in this class.
+ *
+ * @see #STATE_MISSING_TARGET
+ * @see #STATE_NO_IDMAP
+ * @see #STATE_DISABLED
+ * @see #STATE_ENABLED
+ */
+ public final int state;
+
+ /**
+ * User handle for which this overlay applies
+ */
+ public final int userId;
+
+ /**
+ * Create a new OverlayInfo based on source with an updated state.
+ *
+ * @param source the source OverlayInfo to base the new instance on
+ * @param state the new state for the source OverlayInfo
+ */
+ public OverlayInfo(@NonNull OverlayInfo source, int state) {
+ this(source.packageName, source.targetPackageName, source.baseCodePath, state,
+ source.userId);
+ }
+
+ public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
+ @NonNull String baseCodePath, int state, int userId) {
+ this.packageName = packageName;
+ this.targetPackageName = targetPackageName;
+ this.baseCodePath = baseCodePath;
+ this.state = state;
+ this.userId = userId;
+ ensureValidState();
+ }
+
+ public OverlayInfo(Parcel source) {
+ packageName = source.readString();
+ targetPackageName = source.readString();
+ baseCodePath = source.readString();
+ state = source.readInt();
+ userId = source.readInt();
+ ensureValidState();
+ }
+
+ private void ensureValidState() {
+ if (packageName == null) {
+ throw new IllegalArgumentException("packageName must not be null");
+ }
+ if (targetPackageName == null) {
+ throw new IllegalArgumentException("targetPackageName must not be null");
+ }
+ if (baseCodePath == null) {
+ throw new IllegalArgumentException("baseCodePath must not be null");
+ }
+ switch (state) {
+ case STATE_UNKNOWN:
+ case STATE_MISSING_TARGET:
+ case STATE_NO_IDMAP:
+ case STATE_DISABLED:
+ case STATE_ENABLED:
+ break;
+ default:
+ throw new IllegalArgumentException("State " + state + " is not a valid state");
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(packageName);
+ dest.writeString(targetPackageName);
+ dest.writeString(baseCodePath);
+ dest.writeInt(state);
+ dest.writeInt(userId);
+ }
+
+ public static final Parcelable.Creator<OverlayInfo> CREATOR = new Parcelable.Creator<OverlayInfo>() {
+ @Override
+ public OverlayInfo createFromParcel(Parcel source) {
+ return new OverlayInfo(source);
+ }
+
+ @Override
+ public OverlayInfo[] newArray(int size) {
+ return new OverlayInfo[size];
+ }
+ };
+
+ /**
+ * Return true if this overlay is enabled, i.e. should be used to overlay
+ * the resources in the target package.
+ *
+ * Disabled overlay packages are installed but are currently not in use.
+ *
+ * @return true if the overlay is enabled, else false.
+ */
+ public boolean isEnabled() {
+ switch (state) {
+ case STATE_ENABLED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Translate a state to a human readable string. Only intended for
+ * debugging purposes.
+ *
+ * @see #STATE_MISSING_TARGET
+ * @see #STATE_NO_IDMAP
+ * @see #STATE_DISABLED
+ * @see #STATE_ENABLED
+ *
+ * @return a human readable String representing the state.
+ */
+ public static String stateToString(int state) {
+ switch (state) {
+ case STATE_UNKNOWN:
+ return "STATE_UNKNOWN";
+ case STATE_MISSING_TARGET:
+ return "STATE_MISSING_TARGET";
+ case STATE_NO_IDMAP:
+ return "STATE_NO_IDMAP";
+ case STATE_DISABLED:
+ return "STATE_DISABLED";
+ case STATE_ENABLED:
+ return "STATE_ENABLED";
+ default:
+ return "<unknown state>";
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + userId;
+ result = prime * result + state;
+ result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
+ result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode());
+ result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ OverlayInfo other = (OverlayInfo) obj;
+ if (userId != other.userId) {
+ return false;
+ }
+ if (state != other.state) {
+ return false;
+ }
+ if (!packageName.equals(other.packageName)) {
+ return false;
+ }
+ if (!targetPackageName.equals(other.targetPackageName)) {
+ return false;
+ }
+ if (!baseCodePath.equals(other.baseCodePath)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state="
+ + state + " (" + stateToString(state) + "), userId=" + userId + " }";
+ }
+}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index a90b18a877ff..e3e02b1f72a6 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -267,4 +267,33 @@ public abstract class PackageManagerInternal {
}
public abstract void setExternalSourcesPolicy(ExternalSourcesPolicy policy);
+
+ /**
+ * Get all overlay packages for a user.
+ * @param userId The user for which to get the overlays.
+ * @return A list of overlay packages. An empty list is returned if the
+ * user has no installed overlay packages.
+ */
+ public abstract List<PackageInfo> getOverlayPackages(int userId);
+
+ /**
+ * Get the names of all target packages for a user.
+ * @param userId The user for which to get the package names.
+ * @return A list of target package names. This list includes the "android" package.
+ */
+ public abstract List<String> getTargetPackageNames(int userId);
+
+ /**
+ * Set which overlay to use for a package.
+ * @param userId The user for which to update the overlays.
+ * @param targetPackageName The package name of the package for which to update the overlays.
+ * @param overlayPackageNames The complete list of overlay packages that should be enabled for
+ * the target. Previously enabled overlays not specified in the list
+ * will be disabled. Pass in null or an empty list to disable
+ * all overlays. The order of the items is significant if several
+ * overlays modify the same resource.
+ * @return true if all packages names were known by the package manager, false otherwise
+ */
+ public abstract boolean setEnabledOverlayPackages(int userId, String targetPackageName,
+ List<String> overlayPackageNames);
}