Prepare comments and annotations for public FabricatedOverlay API

This patch adds the following items.
* FabricatedOverlay class comments.
* add a FabricatedOverlay contructor
* add a public method `setTargetOverlayable`
* add setResourceValue APIs for
  * int
  * String
  * ParcelFileDescriptor
* comments and annotations for methods in FabricatedOverlay.
  * such as nullability

Bug: 205919743
Test: atest \
        OverlayHostTests \
        OverlayDeviceTests \
        SelfTargetingOverlayDeviceTests \
        OverlayRemountedTest \
        FrameworksServicesTests:com.android.server.om \
        CtsContentTestCases:android.content.om.cts \
        idmap2_tests
Change-Id: I689f5882fc3e1fc74a343106ef310f23a83990cf
diff --git a/core/java/android/content/om/FabricatedOverlay.java b/core/java/android/content/om/FabricatedOverlay.java
index 99fc5a3..e4936bc 100644
--- a/core/java/android/content/om/FabricatedOverlay.java
+++ b/core/java/android/content/om/FabricatedOverlay.java
@@ -35,29 +35,84 @@
 import java.util.Objects;
 
 /**
- * Fabricated Runtime Resource Overlays (FRROs) are overlays generated ar runtime.
+ * FabricatedOverlay describes the content of Fabricated Runtime Resource Overlay (FRRO) that is
+ * used to overlay the app's resources. The app should register the {@link FabricatedOverlay}
+ * instance in an {@link OverlayManagerTransaction} by calling {@link
+ * OverlayManagerTransaction#registerFabricatedOverlay(FabricatedOverlay)}. The FRRO is
+ * created once the transaction is committed successfully.
  *
- * Fabricated overlays are enabled, disabled, and reordered just like normal overlays. The
- * overlayable policies a fabricated overlay fulfills are the same policies the creator of the
- * overlay fulfill. For example, a fabricated overlay created by a platform signed package on the
- * system partition would fulfil the {@code system} and {@code signature} policies.
+ * <p>The app creates a FabricatedOverlay to describe the how to overlay string, integer, and file
+ * type resources. Before creating any frro, please define a target overlayable in {@code
+ * res/values/overlayable.xml} that describes what kind of resources can be overlaid, what kind of
+ * roles or applications can overlay the resources. Here is an example.
  *
- * The owner of a fabricated overlay is the UID that created it. Overlays commit to the overlay
- * manager persist across reboots. When the UID is uninstalled, its fabricated overlays are wiped.
+ * <pre>{@code
+ * <overlayable name="SignatureOverlayable" actor="overlay://theme">
+ *     <!-- The app with the same signature can overlay the below resources -->
+ *     <policy type="signature">
+ *         <item type="color" name="mycolor" />
+ *         <item type="string" name="mystring" />
+ *     </policy>
+ * </overlayable>
+ * }</pre>
  *
- * Processes with {@link Android.Manifest.permission.CHANGE_OVERLAY_PACKAGES} can manage normal
- * overlays and fabricated overlays.
+ * <p>The overlay must assign the target overlayable name just like the above example by calling
+ * {@link #setTargetOverlayable(String)}. Here is an example:
+ *
+ * <pre>{@code
+ * FabricatedOverlay fabricatedOverlay = new FabricatedOverlay("overlay_name",
+ *                                                             context.getPackageName());
+ * fabricatedOverlay.setTargetOverlayable("SignatureOverlayable")
+ * fabricatedOverlay.setResourceValue("mycolor", TypedValue.TYPE_INT_COLOR_ARGB8, Color.White)
+ * fabricatedOverlay.setResourceValue("mystring", TypedValue.TYPE_STRING, "Hello")
+ * }</pre>
+ *
+ * <p>The app can create any {@link FabricatedOverlay} instance by calling the following APIs.
+ *
+ * <ul>
+ *   <li>{@link #setTargetOverlayable(String)}
+ *   <li>{@link #setResourceValue(String, int, int, String)}
+ *   <li>{@link #setResourceValue(String, int, String, String)}
+ *   <li>{@link #setResourceValue(String, ParcelFileDescriptor, String)}
+ * </ul>
+ *
+ * @see OverlayManager
+ * @see OverlayManagerTransaction
  * @hide
  */
 public class FabricatedOverlay {
 
-    /** Retrieves the identifier for this fabricated overlay. */
+    /**
+     * Retrieves the identifier for this fabricated overlay.
+     * @return the overlay identifier
+     *
+     * @hide
+     */
     public OverlayIdentifier getIdentifier() {
         return new OverlayIdentifier(
                 mOverlay.packageName, TextUtils.nullIfEmpty(mOverlay.overlayName));
     }
 
-    public static class Builder {
+    /**
+     * The builder of Fabricated Runtime Resource Overlays(FRROs).
+     *
+     * Fabricated overlays are enabled, disabled, and reordered just like normal overlays. The
+     * overlayable policies a fabricated overlay fulfills are the same policies the creator of the
+     * overlay fulfill. For example, a fabricated overlay created by a platform signed package on
+     * the system partition would fulfil the {@code system} and {@code signature} policies.
+     *
+     * The owner of a fabricated overlay is the UID that created it. Overlays commit to the overlay
+     * manager persist across reboots. When the UID is uninstalled, its fabricated overlays are
+     * wiped.
+     *
+     * Processes with {@code android.Manifest.permission#CHANGE_OVERLAY_PACKAGES} can manage normal
+     * overlays and fabricated overlays.
+     *
+     * @see FabricatedOverlay
+     * @see OverlayManagerTransaction.Builder#registerFabricatedOverlay(FabricatedOverlay)
+     * @hide
+     */
+    public static final class Builder {
         private final String mOwningPackage;
         private final String mName;
         private final String mTargetPackage;
@@ -88,22 +143,16 @@
         }
 
         /**
-         * Constructs a builder for building a fabricated overlay.
+         * Sets the name of the target overlayable to be overlaid.
          *
-         * @param name a name used to uniquely identify the fabricated overlay owned by the caller
-         *             itself.
-         * @param targetPackage the name of the package to overlay
-         */
-        public Builder(@NonNull String name, @NonNull String targetPackage) {
-            mName = OverlayManagerImpl.checkOverlayNameValid(name);
-            mTargetPackage =
-                    Preconditions.checkStringNotEmpty(
-                            targetPackage, "'targetPackage' must not be empty nor null");
-            mOwningPackage = ""; // The package name is filled in OverlayManager.commit
-        }
-
-        /**
-         * Sets the name of the overlayable resources to overlay (can be null).
+         * <p>The target package defines may define several overlayables. The
+         * {@link FabricatedOverlay} should specify which overlayable to be overlaid.
+         *
+         * <p>The target overlayable should be defined in {@code <overlayable>} and pass the value
+         * of its {@code name} attribute as the parameter.
+         *
+         * @param targetOverlayable is a name of the overlayable resources set
+         * @hide
          */
         @NonNull
         public Builder setTargetOverlayable(@Nullable String targetOverlayable) {
@@ -112,27 +161,6 @@
         }
 
         /**
-         * Ensure the resource name is in the form [package]:type/entry.
-         *
-         * @param name name of the target resource to overlay (in the form [package]:type/entry)
-         * @return the valid name
-         */
-        private static String ensureValidResourceName(@NonNull String name) {
-            Objects.requireNonNull(name);
-            final int slashIndex = name.indexOf('/'); /* must contain '/' */
-            final int colonIndex = name.indexOf(':'); /* ':' should before '/' if ':' exist */
-
-            // The minimum length of resource type is "id".
-            Preconditions.checkArgument(
-                    slashIndex >= 0 /* It must contain the type name */
-                    && colonIndex != 0 /* 0 means the package name is empty */
-                    && (slashIndex - colonIndex) > 2 /* The shortest length of type is "id" */,
-                    "\"%s\" is invalid resource name",
-                    name);
-            return name;
-        }
-
-        /**
          * Sets the value of the fabricated overlay for the integer-like types.
          *
          * @param resourceName name of the target resource to overlay (in the form
@@ -141,8 +169,12 @@
          * @param value the unsigned 32 bit integer representing the new value
          * @return the builder itself
          * @see #setResourceValue(String, int, int, String)
-         * @see android.util.TypedValue#type
+         * @see android.util.TypedValue#TYPE_INT_COLOR_ARGB8 android.util.TypedValue#type
+         * @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String, int,
+                       int, String)} instead.
+         * @hide
          */
+        @Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
         @NonNull
         public Builder setResourceValue(
                 @NonNull String resourceName,
@@ -161,8 +193,13 @@
          * @param dataType the data type of the new value
          * @param value the unsigned 32 bit integer representing the new value
          * @param configuration The string representation of the config this overlay is enabled for
-         * @see android.util.TypedValue#type
+         * @return the builder itself
+         * @see android.util.TypedValue#TYPE_INT_COLOR_ARGB8 android.util.TypedValue#type
+         * @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String, int,
+                       int, String)} instead.
+         * @hide
          */
+        @Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
         @NonNull
         public Builder setResourceValue(
                 @NonNull String resourceName,
@@ -171,30 +208,11 @@
                 int value,
                 @Nullable String configuration) {
             ensureValidResourceName(resourceName);
-
-            final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
-            entry.resourceName = resourceName;
-            entry.dataType =
-                    Preconditions.checkArgumentInRange(
-                            dataType,
-                            TypedValue.TYPE_FIRST_INT,
-                            TypedValue.TYPE_LAST_INT,
-                            "dataType");
-            entry.data = value;
-            entry.configuration = configuration;
-            mEntries.add(entry);
+            mEntries.add(generateFabricatedOverlayInternalEntry(resourceName, dataType, value,
+                    configuration));
             return this;
         }
 
-        /** @hide */
-        @IntDef(
-                prefix = {"OVERLAY_TYPE"},
-                value = {
-                    TypedValue.TYPE_STRING,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface StringTypeOverlayResource {}
-
         /**
          * Sets the value of the fabricated overlay for the string-like type.
          *
@@ -203,8 +221,12 @@
          * @param dataType the data type of the new value
          * @param value the string representing the new value
          * @return the builder itself
-         * @see android.util.TypedValue#type
+         * @see android.util.TypedValue#TYPE_STRING android.util.TypedValue#type
+         * @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String, int,
+                       String, String)} instead.
+         * @hide
          */
+        @Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
         @NonNull
         public Builder setResourceValue(
                 @NonNull String resourceName,
@@ -221,8 +243,13 @@
          * @param dataType the data type of the new value
          * @param value the string representing the new value
          * @param configuration The string representation of the config this overlay is enabled for
-         * @see android.util.TypedValue#type
+         * @return the builder itself
+         * @see android.util.TypedValue#TYPE_STRING android.util.TypedValue#type
+         * @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String, int,
+                       String, String)} instead.
+         * @hide
          */
+        @Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
         @NonNull
         public Builder setResourceValue(
                 @NonNull String resourceName,
@@ -230,39 +257,32 @@
                 @NonNull String value,
                 @Nullable String configuration) {
             ensureValidResourceName(resourceName);
-
-            final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
-            entry.resourceName = resourceName;
-            entry.dataType =
-                    Preconditions.checkArgumentInRange(
-                            dataType, TypedValue.TYPE_STRING, TypedValue.TYPE_FRACTION, "dataType");
-            entry.stringData = Objects.requireNonNull(value);
-            entry.configuration = configuration;
-            mEntries.add(entry);
+            mEntries.add(generateFabricatedOverlayInternalEntry(resourceName, dataType, value,
+                    configuration));
             return this;
         }
 
         /**
-         * Sets the value of the fabricated overlay
+         * Sets the value of the fabricated overlay for the file descriptor type.
          *
          * @param resourceName name of the target resource to overlay (in the form
          *     [package]:type/entry)
          * @param value the file descriptor whose contents are the value of the frro
          * @param configuration The string representation of the config this overlay is enabled for
          * @return the builder itself
+         * @deprecated Framework should use {@link FabricatedOverlay#setResourceValue(String,
+                       ParcelFileDescriptor, String)} instead.
+         * @hide
          */
+        @Deprecated(since = "Please use FabricatedOverlay#setResourceValue instead")
         @NonNull
         public Builder setResourceValue(
                 @NonNull String resourceName,
                 @NonNull ParcelFileDescriptor value,
                 @Nullable String configuration) {
             ensureValidResourceName(resourceName);
-
-            final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
-            entry.resourceName = resourceName;
-            entry.binaryData = Objects.requireNonNull(value);
-            entry.configuration = configuration;
-            mEntries.add(entry);
+            mEntries.add(
+                    generateFabricatedOverlayInternalEntry(resourceName, value, configuration));
             return this;
         }
 
@@ -270,22 +290,216 @@
          * Builds an immutable fabricated overlay.
          *
          * @return the fabricated overlay
+         * @hide
          */
         @NonNull
         public FabricatedOverlay build() {
-            final FabricatedOverlayInternal overlay = new FabricatedOverlayInternal();
-            overlay.packageName = mOwningPackage;
-            overlay.overlayName = mName;
-            overlay.targetPackageName = mTargetPackage;
-            overlay.targetOverlayable = mTargetOverlayable;
-            overlay.entries = new ArrayList<>();
-            overlay.entries.addAll(mEntries);
-            return new FabricatedOverlay(overlay);
+            return new FabricatedOverlay(
+                    generateFabricatedOverlayInternal(mOwningPackage, mName, mTargetPackage,
+                            mTargetOverlayable, mEntries));
         }
     }
 
+    private static FabricatedOverlayInternal generateFabricatedOverlayInternal(
+            @NonNull String owningPackage, @NonNull String overlayName,
+            @NonNull String targetPackageName, @Nullable String targetOverlayable,
+            @NonNull ArrayList<FabricatedOverlayInternalEntry> entries) {
+        final FabricatedOverlayInternal overlay = new FabricatedOverlayInternal();
+        overlay.packageName = owningPackage;
+        overlay.overlayName = overlayName;
+        overlay.targetPackageName = targetPackageName;
+        overlay.targetOverlayable = TextUtils.emptyIfNull(targetOverlayable);
+        overlay.entries = new ArrayList<>();
+        overlay.entries.addAll(entries);
+        return overlay;
+    }
+
     final FabricatedOverlayInternal mOverlay;
     private FabricatedOverlay(FabricatedOverlayInternal overlay) {
         mOverlay = overlay;
     }
+
+    /**
+     * Create a fabricated overlay to overlay on the specified package.
+     *
+     * @param overlayName a name used to uniquely identify the fabricated overlay owned by the
+     *                   caller itself.
+     * @param targetPackage the name of the package to be overlaid
+     * @hide
+     */
+    public FabricatedOverlay(@NonNull String overlayName, @NonNull String targetPackage) {
+        this(generateFabricatedOverlayInternal(
+                "" /* owningPackage, The package name is filled commitment */,
+                OverlayManagerImpl.checkOverlayNameValid(overlayName),
+                Preconditions.checkStringNotEmpty(targetPackage,
+                        "'targetPackage' must not be empty nor null"),
+                null /* targetOverlayable */,
+                new ArrayList<>()));
+    }
+
+    /**
+     * Set the target overlayable name of the overlay
+     *
+     * The target package defines may define several overlayables. The {@link FabricatedOverlay}
+     * should specify which overlayable to be overlaid.
+     *
+     * @param targetOverlayable the overlayable name defined in target package.
+     * @hide
+     */
+    public void setTargetOverlayable(@Nullable String targetOverlayable) {
+        mOverlay.targetOverlayable = TextUtils.emptyIfNull(targetOverlayable);
+    }
+
+    /**
+     * Return the target overlayable name of the overlay
+     *
+     * The target package defines may define several overlayables. The {@link FabricatedOverlay}
+     * should specify which overlayable to be overlaid.
+     *
+     * @return the target overlayable name.
+     * @hide
+     */
+    @Nullable
+    public String getTargetOverlayable() {
+        return mOverlay.targetOverlayable;
+    }
+
+    /**
+     * Ensure the resource name is in the form [package]:type/entry.
+     *
+     * @param name name of the target resource to overlay (in the form [package]:type/entry)
+     * @return the valid name
+     */
+    private static String ensureValidResourceName(@NonNull String name) {
+        Objects.requireNonNull(name);
+        final int slashIndex = name.indexOf('/'); /* must contain '/' */
+        final int colonIndex = name.indexOf(':'); /* ':' should before '/' if ':' exist */
+
+        // The minimum length of resource type is "id".
+        Preconditions.checkArgument(
+                slashIndex >= 0 /* It must contain the type name */
+                        && colonIndex != 0 /* 0 means the package name is empty */
+                        && (slashIndex - colonIndex) > 2 /* The shortest length of type is "id" */,
+                "\"%s\" is invalid resource name",
+                name);
+        return name;
+    }
+
+    @NonNull
+    private static FabricatedOverlayInternalEntry generateFabricatedOverlayInternalEntry(
+            @NonNull String resourceName,
+            @IntRange(from = TypedValue.TYPE_FIRST_INT, to = TypedValue.TYPE_LAST_INT) int dataType,
+            int value, @Nullable String configuration) {
+        final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
+        entry.resourceName = resourceName;
+        entry.dataType =
+                Preconditions.checkArgumentInRange(
+                        dataType,
+                        TypedValue.TYPE_FIRST_INT,
+                        TypedValue.TYPE_LAST_INT,
+                        "dataType");
+        entry.data = value;
+        entry.configuration = configuration;
+        return entry;
+    }
+
+    @NonNull
+    private static FabricatedOverlayInternalEntry generateFabricatedOverlayInternalEntry(
+            @NonNull String resourceName, @StringTypeOverlayResource int dataType,
+            @NonNull String value, @Nullable String configuration) {
+        final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
+        entry.resourceName = resourceName;
+        entry.dataType =
+                Preconditions.checkArgumentInRange(
+                        dataType, TypedValue.TYPE_STRING, TypedValue.TYPE_FRACTION, "dataType");
+        entry.stringData = Objects.requireNonNull(value);
+        entry.configuration = configuration;
+        return entry;
+    }
+
+    @NonNull
+    private static FabricatedOverlayInternalEntry generateFabricatedOverlayInternalEntry(
+            @NonNull String resourceName, @NonNull ParcelFileDescriptor parcelFileDescriptor,
+            @Nullable String configuration) {
+        final FabricatedOverlayInternalEntry entry = new FabricatedOverlayInternalEntry();
+        entry.resourceName = resourceName;
+        entry.binaryData = Objects.requireNonNull(parcelFileDescriptor);
+        entry.configuration = configuration;
+        return entry;
+    }
+
+    /**
+     * Sets the resource value in the fabricated overlay for the integer-like types with the
+     * configuration.
+     *
+     * @param resourceName name of the target resource to overlay (in the form
+     *     [package]:type/entry)
+     * @param dataType the data type of the new value
+     * @param value the integer representing the new value
+     * @param configuration The string representation of the config this overlay is enabled for
+     * @see android.util.TypedValue#TYPE_INT_COLOR_ARGB8 android.util.TypedValue#type
+     * @hide
+     */
+    @NonNull
+    public void setResourceValue(
+            @NonNull String resourceName,
+            @IntRange(from = TypedValue.TYPE_FIRST_INT, to = TypedValue.TYPE_LAST_INT) int dataType,
+            int value,
+            @Nullable String configuration) {
+        ensureValidResourceName(resourceName);
+        mOverlay.entries.add(generateFabricatedOverlayInternalEntry(resourceName, dataType, value,
+                configuration));
+    }
+
+    /** @hide */
+    @IntDef(
+            prefix = {"OVERLAY_TYPE"},
+            value = {
+                    TypedValue.TYPE_STRING,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StringTypeOverlayResource {}
+
+    /**
+     * Sets the resource value in the fabricated overlay for the string-like type with the
+     * configuration.
+     *
+     * @param resourceName name of the target resource to overlay (in the form
+     *     [package]:type/entry)
+     * @param dataType the data type of the new value
+     * @param value the string representing the new value
+     * @param configuration The string representation of the config this overlay is enabled for
+     * @see android.util.TypedValue#TYPE_STRING android.util.TypedValue#type
+     * @hide
+     */
+    @NonNull
+    public void setResourceValue(
+            @NonNull String resourceName,
+            @StringTypeOverlayResource int dataType,
+            @NonNull String value,
+            @Nullable String configuration) {
+        ensureValidResourceName(resourceName);
+        mOverlay.entries.add(generateFabricatedOverlayInternalEntry(resourceName, dataType, value,
+                configuration));
+    }
+
+    /**
+     * Sets the resource value in the fabricated overlay for the file descriptor type with the
+     * configuration.
+     *
+     * @param resourceName name of the target resource to overlay (in the form
+     *     [package]:type/entry)
+     * @param value the file descriptor whose contents are the value of the frro
+     * @param configuration The string representation of the config this overlay is enabled for
+     * @hide
+     */
+    @NonNull
+    public void setResourceValue(
+            @NonNull String resourceName,
+            @NonNull ParcelFileDescriptor value,
+            @Nullable String configuration) {
+        ensureValidResourceName(resourceName);
+        mOverlay.entries.add(
+                generateFabricatedOverlayInternalEntry(resourceName, value, configuration));
+    }
 }