Sunday, 5 March 2023

How to correctly define and use enums in Stable AIDL interfaces?

I am interested in defining a Stable AIDL interface: https://source.android.com/docs/core/architecture/aidl/stable-aidl with stability: "vintf" and @VintfStability annotation on all defined interfaces, parcelables, enums.

While doing that, I am interested in defining a custom enum as a return type for one of the Stable AIDL interfaces. For example:

interface IMyStableAidlInterface {
     MyEnum example();
}

Before Stable AIDL, I believe we could define our own custom enum that implements a Parcelable like this inside of a Java file. This worked well for me before Stable AIDL:

enum MyCustomEnumParcelable implements Parcelable {
A,
B;

@Override
public int describeContents() {
    ...
}

@Override
public void writeToParcel(final Parcel dest, final int flags) {
    ...
}

public static final Creator<MyCustomEnumParcelable> CREATOR = new Creator<MyCustomEnumParcelable>() {
   ...
}

Today with Stable AIDL, I read that we are not allowed to define custom enum parcelables like this and that enums should be defined in AIDL files directly (please correct me if I am wrong! I would be open to defining a custom enum implementing a parcelable, if that is allowed with Stable AIDL). Reference: https://source.android.com/docs/core/architecture/aidl/stable-aidl :

Interfaces can contain only structured data. Parcelables representing the desired types are automatically created based on their AIDL definition and are automatically marshalled and unmarshalled.

Interfaces in stable AIDL are similar to traditional interfaces, with the exception that they aren't allowed to use unstructured parcelables (because these aren't stable!). The primary difference in stable AIDL is how parcelables are defined. Previously, parcelables were forward declared; in stable AIDL, parcelables fields and variables are defined explicitly.

With that said, it seems the only way to define enums in Stable AIDL is directly in *.aidl file:

@VintfStability
enum MyEnum {
  A,
  B 
}

However, it seems when this gets generate, the backend Java code ultimately becomes the following @interface with constants:

public @interface MyEnum {
    public static final byte A = 0;
    public static final byte B = 1;
}

Is there any way that I can define my own enum and use the enum in the way that enums are normally used in Java?

For example, given my Stable AIDL inteface above, my Java AIDL Service will need to implement the following. I'd like for it to be able to return MyEnum.A and use the return type MyEnum:

@Override
public MyEnum example() {
   // I would like to be able to do something like this... 
   return MyEnum.A;
}

However, it doesn't seem to be possible because MyEnum is generated with @interface. If enums ultimately become @interface, what is the motivation of having the AIDL interfaces with return types that are enums? Perhaps I am not understanding how enums should be used in Stable AIDL, I can't seem to find good documentation on this. Would my Service's implementation ultimately need to be something like public int example() instead? I was hoping to not have to do that. In general, what would be the best practice or recommended way to use enums as parameters and return types in Stable AIDL interfaces?

Any help would be greatly appreciated! Thank you!



from How to correctly define and use enums in Stable AIDL interfaces?

No comments:

Post a Comment