Add documentation notes for enums

Also add a section about backwards compatibility to
@PrivacySandboxValue.

Relnote: Add support for enum classes annotated with
@PrivacySandboxValue. Note that backwards compatility requires no
changes to enum constants (reordering, renaming, adding new constants).

Bug: 323369085
Change-Id: I3b36b1ebec08371d8c6d16e07727a821d454746f
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt
index 6f4b716..9c0cec1 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt
@@ -62,7 +62,7 @@
         assertThat(ToolMetadata.parseFrom(resourceMap[expectedMetadataRelativePath]))
             .isEqualTo(
                 ToolMetadata.newBuilder()
-                    .setCodeGenerationVersion(3)
+                    .setCodeGenerationVersion(4)
                     .build()
             )
     }
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt
index 548b00b..5cf9554 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt
@@ -365,8 +365,8 @@
     fun parameterWithGenerics_fails() {
         checkSourceFails(serviceMethod("suspend fun foo(x: MutableList<Int>)"))
             .containsExactlyErrors(
-                "Error in com.mysdk.MySdk.foo: only primitives, lists, data classes annotated " +
-                    "with @PrivacySandboxValue, interfaces annotated with " +
+                "Error in com.mysdk.MySdk.foo: only primitives, lists, data/enum classes " +
+                    "annotated with @PrivacySandboxValue, interfaces annotated with " +
                     "@PrivacySandboxCallback or @PrivacySandboxInterface, and " +
                     "SdkActivityLaunchers are supported as parameter types."
             )
@@ -384,8 +384,8 @@
     fun parameterLambda_fails() {
         checkSourceFails(serviceMethod("suspend fun foo(x: (Int) -> Int)"))
             .containsExactlyErrors(
-                "Error in com.mysdk.MySdk.foo: only primitives, lists, data classes annotated " +
-                    "with @PrivacySandboxValue, interfaces annotated with " +
+                "Error in com.mysdk.MySdk.foo: only primitives, lists, data/enum classes " +
+                    "annotated with @PrivacySandboxValue, interfaces annotated with " +
                     "@PrivacySandboxCallback " + "or @PrivacySandboxInterface, and " +
                     "SdkActivityLaunchers are supported as parameter types."
             )
@@ -406,9 +406,9 @@
                 """
         )
         checkSourceFails(source).containsExactlyErrors(
-            "Error in com.mysdk.MySdk.foo: only primitives, lists, data classes annotated with " +
-                "@PrivacySandboxValue, interfaces annotated with @PrivacySandboxInterface, and " +
-                "SdkActivityLaunchers are supported as return types."
+            "Error in com.mysdk.MySdk.foo: only primitives, lists, data/enum classes annotated " +
+                "with @PrivacySandboxValue, interfaces annotated with @PrivacySandboxInterface, " +
+                "and SdkActivityLaunchers are supported as return types."
         )
     }
 
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/ValueParserTest.kt b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/ValueParserTest.kt
index 858ee45..45d4d94 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/ValueParserTest.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/ValueParserTest.kt
@@ -273,7 +273,7 @@
         )
         checkSourceFails(dataClass)
             .containsExactlyErrors(
-                "Error in com.mysdk.MySdkRequest.foo: only primitives, lists, data classes " +
+                "Error in com.mysdk.MySdkRequest.foo: only primitives, lists, data/enum classes " +
                     "annotated with @PrivacySandboxValue, interfaces annotated with " +
                     "@PrivacySandboxInterface, and SdkActivityLaunchers are supported as " +
                     "properties."
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/Metadata.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/Metadata.kt
index 3fd042f..9101808 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/Metadata.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/Metadata.kt
@@ -24,7 +24,7 @@
     /** Tool metadata message. It's serialized and stored in every SDK API descriptor. */
     val toolMetadata: ToolMetadata =
         ToolMetadata.newBuilder()
-            .setCodeGenerationVersion(3)
+            .setCodeGenerationVersion(4)
             .build()
 
     /** Relative path to metadata file in SDK API descriptor jar. */
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/validator/ModelValidator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/validator/ModelValidator.kt
index 7074ebf..b7cbcc3 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/validator/ModelValidator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/validator/ModelValidator.kt
@@ -93,7 +93,7 @@
                 if (method.parameters.any { !(isValidInterfaceParameterType(it.type)) }) {
                     errors.add(
                         "Error in ${annotatedInterface.type.qualifiedName}.${method.name}: " +
-                            "only primitives, lists, data classes annotated with " +
+                            "only primitives, lists, data/enum classes annotated with " +
                             "@PrivacySandboxValue, interfaces annotated with " +
                             "@PrivacySandboxCallback or @PrivacySandboxInterface, and " +
                             "SdkActivityLaunchers are supported as parameter types."
@@ -102,7 +102,7 @@
                 if (!isValidInterfaceReturnType(method.returnType)) {
                     errors.add(
                         "Error in ${annotatedInterface.type.qualifiedName}.${method.name}: " +
-                            "only primitives, lists, data classes annotated with " +
+                            "only primitives, lists, data/enum classes annotated with " +
                             "@PrivacySandboxValue, interfaces annotated with " +
                             "@PrivacySandboxInterface, and SdkActivityLaunchers are supported as " +
                             "return types."
@@ -121,7 +121,7 @@
                 if (!isValidValuePropertyType(property.type)) {
                     errors.add(
                         "Error in ${value.type.qualifiedName}.${property.name}: " +
-                            "only primitives, lists, data classes annotated with " +
+                            "only primitives, lists, data/enum classes annotated with " +
                             "@PrivacySandboxValue, interfaces annotated with " +
                             "@PrivacySandboxInterface, and SdkActivityLaunchers are supported as " +
                             "properties."
@@ -137,7 +137,7 @@
                 if (method.parameters.any { !isValidCallbackParameterType(it.type) }) {
                     errors.add(
                         "Error in ${callback.type.qualifiedName}.${method.name}: " +
-                            "only primitives, lists, data classes annotated with " +
+                            "only primitives, lists, data/enum classes annotated with " +
                             "@PrivacySandboxValue, interfaces annotated with " +
                             "@PrivacySandboxInterface, and SdkActivityLaunchers are supported as " +
                             "callback parameter types."
diff --git a/privacysandbox/tools/tools-core/src/test/java/androidx/privacysandbox/tools/core/validator/ModelValidatorTest.kt b/privacysandbox/tools/tools-core/src/test/java/androidx/privacysandbox/tools/core/validator/ModelValidatorTest.kt
index c76a38a..e4c80eb 100644
--- a/privacysandbox/tools/tools-core/src/test/java/androidx/privacysandbox/tools/core/validator/ModelValidatorTest.kt
+++ b/privacysandbox/tools/tools-core/src/test/java/androidx/privacysandbox/tools/core/validator/ModelValidatorTest.kt
@@ -293,10 +293,10 @@
         val validationResult = ModelValidator.validate(api)
         assertThat(validationResult.isFailure).isTrue()
         assertThat(validationResult.errors).containsExactly(
-            "Error in com.mysdk.MySdk.returnFoo: only primitives, lists, data classes annotated " +
-                "with @PrivacySandboxValue, interfaces annotated with @PrivacySandboxInterface, " +
-                "and SdkActivityLaunchers are supported as return types.",
-            "Error in com.mysdk.MySdk.receiveFoo: only primitives, lists, data classes " +
+            "Error in com.mysdk.MySdk.returnFoo: only primitives, lists, data/enum classes " +
+                "annotated with @PrivacySandboxValue, interfaces annotated with " +
+                "@PrivacySandboxInterface, and SdkActivityLaunchers are supported as return types.",
+            "Error in com.mysdk.MySdk.receiveFoo: only primitives, lists, data/enum classes " +
                 "annotated with @PrivacySandboxValue, interfaces annotated with " +
                 "@PrivacySandboxCallback or @PrivacySandboxInterface, and SdkActivityLaunchers " +
                 "are supported as parameter types."
@@ -379,9 +379,9 @@
         val validationResult = ModelValidator.validate(api)
         assertThat(validationResult.isFailure).isTrue()
         assertThat(validationResult.errors).containsExactly(
-            "Error in com.mysdk.Foo.bar: only primitives, lists, data classes annotated with " +
-                "@PrivacySandboxValue, interfaces annotated with @PrivacySandboxInterface, and " +
-                "SdkActivityLaunchers are supported as properties."
+            "Error in com.mysdk.Foo.bar: only primitives, lists, data/enum classes annotated " +
+                "with @PrivacySandboxValue, interfaces annotated with @PrivacySandboxInterface, " +
+                "and SdkActivityLaunchers are supported as properties."
         )
     }
 
@@ -410,7 +410,7 @@
         val validationResult = ModelValidator.validate(api)
         assertThat(validationResult.isFailure).isTrue()
         assertThat(validationResult.errors).containsExactly(
-            "Error in com.mysdk.MySdkCallback.foo: only primitives, lists, data classes " +
+            "Error in com.mysdk.MySdkCallback.foo: only primitives, lists, data/enum classes " +
                 "annotated with @PrivacySandboxValue, interfaces annotated with " +
                 "@PrivacySandboxInterface, and SdkActivityLaunchers are supported as callback " +
                 "parameter types."
diff --git a/privacysandbox/tools/tools/src/main/java/androidx/privacysandbox/tools/PrivacySandboxValue.kt b/privacysandbox/tools/tools/src/main/java/androidx/privacysandbox/tools/PrivacySandboxValue.kt
index 7b002d9..97383f9 100644
--- a/privacysandbox/tools/tools/src/main/java/androidx/privacysandbox/tools/PrivacySandboxValue.kt
+++ b/privacysandbox/tools/tools/src/main/java/androidx/privacysandbox/tools/PrivacySandboxValue.kt
@@ -19,13 +19,22 @@
 /**
  * Annotated values that can be sent to/from SDKs in the Privacy Sandbox.
  *
- * The values should be public Kotlin data classes that only contain immutable properties with types
- * supported by the sandbox (primitives, [PrivacySandboxInterface], [PrivacySandboxValue], or lists
- * of primitives or [PrivacySandboxValue]). [PrivacySandboxCallback] interfaces are not allowed.
+ * The values should be public Kotlin data classes or enum classes.
+ *
+ * For data classes, they should only contain immutable properties with types supported by the
+ * sandbox (primitives, [PrivacySandboxInterface], [PrivacySandboxValue], or lists of primitives or
+ * [PrivacySandboxValue]). [PrivacySandboxCallback] interfaces are not allowed.
+ *
+ * For enum classes, they should only contain basic enum constants.
  *
  * Values cannot have functions, type parameters or properties with default values.
  *
- * Usage example:
+ * Backwards compatibility: After the data/enum class is first published, no new fields should be
+ * added, and existing fields should not be renamed, reordered, or changed to another type, unless
+ * the SDK major version is incremented. This is required for backwards compatibility with possibly
+ * mismatching SDK versions on the client side.
+ *
+ * Data class usage example:
  * ```
  * @PrivacySandboxValue
  * data class ComplicatedStructure(
@@ -39,6 +48,15 @@
  *   val maybeInterface: MyInterface?,
  * )
  * ```
+ *
+ * Enum class usage example:
+ * ```
+ * @PrivacySandboxValue
+ * enum class Direction(
+ *   UP,
+ *   DOWN,
+ * )
+ * ```
  */
 @Retention(AnnotationRetention.RUNTIME)
 @Target(AnnotationTarget.CLASS)