diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/content/Context.java | 10 | ||||
| -rw-r--r-- | core/java/android/content/Intent.java | 34 | ||||
| -rw-r--r-- | core/java/android/content/om/IOverlayManager.aidl | 129 | ||||
| -rw-r--r-- | core/java/android/content/om/OverlayInfo.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/content/om/OverlayInfo.java | 263 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManagerInternal.java | 29 |
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); } |
