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)