Add overlay management functions into OverlayManager
Self-Targeting apps can manage the overlays by the following classes.
* OverlayManager
* OverlayManagerTransaction
For OverlayManager, it provides 2 functions for the app.
* Start a overlay manager transaction
OverlayManager#beginTransaction()
* List the registered overlays
OverlayManager#getOverlayInfosForTarget(targetPackage).
For OverlayManagerTransaction, it provides 3 functions for the app.
* register a FabricatedOverlay
OverlayManagerTransaction#registerFabricatedOverlay
* unregister a FabricatedOverlay
OverlayManagerTransaction#unregisterFabricatedOverlay
* commit the transaction
OverlayManagerTransaction#commit
Test: atest \
OverlayHostTests \
OverlayDeviceTests \
SelfTargetingOverlayDeviceTests \
OverlayRemountedTest \
FrameworksServicesTests:com.android.server.om \
CtsContentTestCases:android.content.om.cts \
idmap2_tests
Bug: 205919743
Change-Id: I3b0b60a30689b3d033f96cfcf02e2f67b480f207
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package android.content.om;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.NonUiContext;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
@@ -25,12 +26,16 @@ import android.compat.Compatibility;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.internal.content.om.OverlayManagerImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -76,6 +81,7 @@ public class OverlayManager {
|
||||
|
||||
private final IOverlayManager mService;
|
||||
private final Context mContext;
|
||||
private final OverlayManagerImpl mOverlayManagerImpl;
|
||||
|
||||
/**
|
||||
* Pre R a {@link java.lang.SecurityException} would only be thrown by setEnabled APIs (e
|
||||
@@ -117,6 +123,7 @@ public class OverlayManager {
|
||||
public OverlayManager(Context context, IOverlayManager service) {
|
||||
mContext = context;
|
||||
mService = service;
|
||||
mOverlayManagerImpl = new OverlayManagerImpl(context);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -301,6 +308,17 @@ public class OverlayManager {
|
||||
* @hide
|
||||
*/
|
||||
public void commit(@NonNull final OverlayManagerTransaction transaction) {
|
||||
if (transaction.isSelfTargetingTransaction()
|
||||
|| mService == null
|
||||
|| mService.asBinder() == null) {
|
||||
try {
|
||||
commitSelfTarget(transaction);
|
||||
} catch (PackageManager.NameNotFoundException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mService.commit(transaction);
|
||||
} catch (RemoteException e) {
|
||||
@@ -332,4 +350,48 @@ public class OverlayManager {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a OverlayManagerTransaction.Builder to build out a overlay manager transaction.
|
||||
*
|
||||
* @return a builder of the overlay manager transaction.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public OverlayManagerTransaction.Builder beginTransaction() {
|
||||
return new OverlayManagerTransaction.Builder(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the self-targeting transaction to register or unregister overlays.
|
||||
*
|
||||
* <p>Applications can request OverlayManager to register overlays and unregister the registered
|
||||
* overlays via {@link OverlayManagerTransaction}.
|
||||
*
|
||||
* @throws IOException if there is a file operation error.
|
||||
* @throws PackageManager.NameNotFoundException if the package name is not found.
|
||||
* @hide
|
||||
*/
|
||||
@NonUiContext
|
||||
void commitSelfTarget(@NonNull final OverlayManagerTransaction transaction)
|
||||
throws PackageManager.NameNotFoundException, IOException {
|
||||
synchronized (mOverlayManagerImpl) {
|
||||
mOverlayManagerImpl.commit(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the related information of overlays for {@code targetPackageName}.
|
||||
*
|
||||
* @param targetPackageName the target package name
|
||||
* @return a list of overlay information
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
@NonUiContext
|
||||
public List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName) {
|
||||
synchronized (mOverlayManagerImpl) {
|
||||
return mOverlayManagerImpl.getOverlayInfosForTarget(targetPackageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,19 +20,22 @@ import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.NonUiContext;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Container for a batch of requests to the OverlayManagerService.
|
||||
@@ -53,13 +56,16 @@ public class OverlayManagerTransaction
|
||||
// TODO: remove @hide from this class when OverlayManager is added to the
|
||||
// SDK, but keep OverlayManagerTransaction.Request @hidden
|
||||
private final List<Request> mRequests;
|
||||
private final OverlayManager mOverlayManager;
|
||||
|
||||
OverlayManagerTransaction(@NonNull final List<Request> requests) {
|
||||
OverlayManagerTransaction(
|
||||
@NonNull final List<Request> requests, @Nullable OverlayManager overlayManager) {
|
||||
checkNotNull(requests);
|
||||
if (requests.contains(null)) {
|
||||
throw new IllegalArgumentException("null request");
|
||||
}
|
||||
mRequests = requests;
|
||||
mOverlayManager = overlayManager;
|
||||
}
|
||||
|
||||
private OverlayManagerTransaction(@NonNull final Parcel source) {
|
||||
@@ -72,6 +78,7 @@ public class OverlayManagerTransaction
|
||||
final Bundle extras = source.readBundle(null);
|
||||
mRequests.add(new Request(request, overlay, userId, extras));
|
||||
}
|
||||
mOverlayManager = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,6 +163,20 @@ public class OverlayManagerTransaction
|
||||
*/
|
||||
public static class Builder {
|
||||
private final List<Request> mRequests = new ArrayList<>();
|
||||
@Nullable private final OverlayManager mOverlayManager;
|
||||
|
||||
public Builder() {
|
||||
mOverlayManager = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The transaction builder for self-targeting.
|
||||
*
|
||||
* @param overlayManager is not null if the transaction is for self-targeting.
|
||||
*/
|
||||
Builder(@NonNull OverlayManager overlayManager) {
|
||||
mOverlayManager = Objects.requireNonNull(overlayManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request that an overlay package be enabled and change its loading
|
||||
@@ -205,7 +226,10 @@ public class OverlayManagerTransaction
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Builder registerFabricatedOverlay(@NonNull FabricatedOverlay overlay) {
|
||||
Objects.requireNonNull(overlay);
|
||||
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putParcelable(Request.BUNDLE_FABRICATED_OVERLAY, overlay.mOverlay);
|
||||
mRequests.add(new Request(Request.TYPE_REGISTER_FABRICATED, overlay.getIdentifier(),
|
||||
@@ -220,7 +244,10 @@ public class OverlayManagerTransaction
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Builder unregisterFabricatedOverlay(@NonNull OverlayIdentifier overlay) {
|
||||
Objects.requireNonNull(overlay);
|
||||
|
||||
mRequests.add(new Request(Request.TYPE_UNREGISTER_FABRICATED, overlay,
|
||||
UserHandle.USER_ALL));
|
||||
return this;
|
||||
@@ -233,8 +260,9 @@ public class OverlayManagerTransaction
|
||||
* @see OverlayManager#commit
|
||||
* @return a new transaction
|
||||
*/
|
||||
@NonNull
|
||||
public OverlayManagerTransaction build() {
|
||||
return new OverlayManagerTransaction(mRequests);
|
||||
return new OverlayManagerTransaction(mRequests, mOverlayManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,4 +297,23 @@ public class OverlayManagerTransaction
|
||||
return new OverlayManagerTransaction[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Commit the overlay manager transaction to register or unregister overlays for self-targeting.
|
||||
*
|
||||
* <p>Applications can register overlays and unregister the registered overlays via {@link
|
||||
* OverlayManagerTransaction}.
|
||||
*
|
||||
* @throws IOException if there is a file operation error.
|
||||
* @throws PackageManager.NameNotFoundException if the package name is not found.
|
||||
* @hide
|
||||
*/
|
||||
@NonUiContext
|
||||
public void commit() throws PackageManager.NameNotFoundException, IOException {
|
||||
mOverlayManager.commitSelfTarget(this);
|
||||
}
|
||||
|
||||
boolean isSelfTargetingTransaction() {
|
||||
return mOverlayManager != null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user