Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec915c66 authored by felkachang's avatar felkachang Committed by Felka Chang
Browse files

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
parent c04d8de7
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+50 −3
Original line number Diff line number Diff line
@@ -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;
    }
}