From d6018d5984e6c0071f600c18ae21414d87f589e0 Mon Sep 17 00:00:00 2001 From: Jeongik Cha Date: Tue, 13 Oct 2020 23:49:55 +0900 Subject: Expose 'ParcelableHolder' as SystemApi ParcelableHolder is the way to extend already defined parcelables. So, it's supposed to be used by OEM's modules. For Parcelable to be used by the OEM's module, it should be exposed as SystemApi Bug: 146611855 Test: atest aidl_unittests aidl_integration_test CtsNdkBinderTest Change-Id: I3d3e3d6b22ffd128dcfc8281d998ee3f55a398c5 --- api/module-lib-current.txt | 2 -- api/system-current.txt | 16 +++++++++ core/java/android/os/Parcelable.java | 4 +-- core/java/android/os/ParcelableHolder.java | 54 ++++++++++++++++++++++++++---- non-updatable-api/module-lib-current.txt | 2 -- non-updatable-api/system-current.txt | 16 +++++++++ 6 files changed, 82 insertions(+), 12 deletions(-) diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index f07f2f34425b..2f0ae78f7e2d 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -47,8 +47,6 @@ package android.os { public interface Parcelable { method public default int getStability(); - field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0 - field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1 } public class StatsFrameworkInitializer { diff --git a/api/system-current.txt b/api/system-current.txt index 8db99aa097a7..6475d81067cd 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8350,6 +8350,22 @@ package android.os { method public boolean hasSingleFileDescriptor(); } + public interface Parcelable { + field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0 + field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1 + } + + public final class ParcelableHolder implements android.os.Parcelable { + ctor public ParcelableHolder(int); + method public int describeContents(); + method @Nullable public T getParcelable(@NonNull Class); + method public int getStability(); + method public void readFromParcel(@NonNull android.os.Parcel); + method public boolean setParcelable(@Nullable android.os.Parcelable); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public final class PowerManager { method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend(); diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java index f14f66b07630..7a624e1da26c 100644 --- a/core/java/android/os/Parcelable.java +++ b/core/java/android/os/Parcelable.java @@ -120,7 +120,7 @@ public interface Parcelable { * @see ParcelableHolder * @hide */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) public static final int PARCELABLE_STABILITY_LOCAL = 0x0000; /** * Something that is meant to be used between system and vendor. @@ -128,7 +128,7 @@ public interface Parcelable { * @see ParcelableHolder * @hide */ - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) public static final int PARCELABLE_STABILITY_VINTF = 0x0001; /** diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java index 181f94b39841..95c07b6b2451 100644 --- a/core/java/android/os/ParcelableHolder.java +++ b/core/java/android/os/ParcelableHolder.java @@ -18,12 +18,54 @@ package android.os; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.util.MathUtils; /** - * Parcelable containing the other Parcelable object. + * ParcelableHolder is a Parcelable which can contain another Parcelable. + * The main use case of ParcelableHolder is to make a Parcelable extensible. + * For example, an AOSP-defined Parcelable AospDefinedParcelable + * is expected to be extended by device implementers for their value-add features. + * Previously without ParcelableHolder, the device implementers had to + * directly modify the Parcelable to add more fields: + *
 {@code
+ * parcelable AospDefinedParcelable {
+ *   int a;
+ *   String b;
+ *   String x; // added by a device implementer
+ *   int[] y; // added by a device implementer
+ * }}
+ * + * This practice is very error-prone because the fields added by the device implementer + * might have a conflict when the Parcelable is revisioned in the next releases of Android. + * + * Using ParcelableHolder, one can define an extension point in a Parcelable. + *
 {@code
+ * parcelable AospDefinedParcelable {
+ *   int a;
+ *   String b;
+ *   ParcelableHolder extension;
+ * }}
+ * Then the device implementers can define their own Parcelable for their extension. + * + *
 {@code
+ * parcelable OemDefinedParcelable {
+ *   String x;
+ *   int[] y;
+ * }}
+ * Finally, the new Parcelable can be attached to the original Parcelable via + * the ParcelableHolder field. + * + *
 {@code
+ * AospDefinedParcelable ap = ...;
+ * OemDefinedParcelable op = new OemDefinedParcelable();
+ * op.x = ...;
+ * op.y = ...;
+ * ap.extension.setParcelable(op);}
+ * * @hide */ +@SystemApi public final class ParcelableHolder implements Parcelable { /** * This is set by {@link #setParcelable}. @@ -80,7 +122,7 @@ public final class ParcelableHolder implements Parcelable { * Write a parcelable into ParcelableHolder, the previous parcelable will be removed. * @return {@code false} if the parcelable's stability is more unstable ParcelableHolder. */ - public synchronized boolean setParcelable(@Nullable Parcelable p) { + public boolean setParcelable(@Nullable Parcelable p) { // a ParcelableHolder can only hold things at its stability or higher if (p != null && this.getStability() > p.getStability()) { return false; @@ -99,7 +141,7 @@ public final class ParcelableHolder implements Parcelable { * the type written by (@link #setParcelable}. */ @Nullable - public synchronized T getParcelable(@NonNull Class clazz) { + public T getParcelable(@NonNull Class clazz) { if (mParcel == null) { if (!clazz.isInstance(mParcelable)) { return null; @@ -123,7 +165,7 @@ public final class ParcelableHolder implements Parcelable { /** * Read ParcelableHolder from a parcel. */ - public synchronized void readFromParcel(@NonNull Parcel parcel) { + public void readFromParcel(@NonNull Parcel parcel) { this.mStability = parcel.readInt(); mParcelable = null; @@ -145,7 +187,7 @@ public final class ParcelableHolder implements Parcelable { } @Override - public synchronized void writeToParcel(@NonNull Parcel parcel, int flags) { + public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeInt(this.mStability); if (mParcel != null) { @@ -166,7 +208,7 @@ public final class ParcelableHolder implements Parcelable { } @Override - public synchronized int describeContents() { + public int describeContents() { if (mParcel != null) { return mParcel.hasFileDescriptors() ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0; } diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt index af959550f9bd..d4d9f62964c8 100644 --- a/non-updatable-api/module-lib-current.txt +++ b/non-updatable-api/module-lib-current.txt @@ -7,8 +7,6 @@ package android.os { public interface Parcelable { method public default int getStability(); - field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0 - field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1 } public class StatsServiceManager { diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 6a217b2ce847..7d5d0a65d43e 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -7270,6 +7270,22 @@ package android.os { method public boolean hasSingleFileDescriptor(); } + public interface Parcelable { + field public static final int PARCELABLE_STABILITY_LOCAL = 0; // 0x0 + field public static final int PARCELABLE_STABILITY_VINTF = 1; // 0x1 + } + + public final class ParcelableHolder implements android.os.Parcelable { + ctor public ParcelableHolder(int); + method public int describeContents(); + method @Nullable public T getParcelable(@NonNull Class); + method public int getStability(); + method public void readFromParcel(@NonNull android.os.Parcel); + method public boolean setParcelable(@Nullable android.os.Parcelable); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public final class PowerManager { method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend(); -- cgit v1.2.3-59-g8ed1b