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:
felkachang
2022-09-19 13:06:23 +08:00
committed by Felka Chang
parent c04d8de7c4
commit ec915c669c
2 changed files with 112 additions and 3 deletions

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}