Merge "Add a module for Material 3 apdative" into androidx-main
diff --git a/activity/activity-compose/api/current.ignore b/activity/activity-compose/api/current.ignore
new file mode 100644
index 0000000..771cee8
--- /dev/null
+++ b/activity/activity-compose/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.compose.ManagedActivityResultLauncher#launch(I, androidx.core.app.ActivityOptionsCompat) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.compose.ManagedActivityResultLauncher.launch(I input, androidx.core.app.ActivityOptionsCompat options)
diff --git a/activity/activity-compose/api/current.txt b/activity/activity-compose/api/current.txt
index ff9df4f..48d220b 100644
--- a/activity/activity-compose/api/current.txt
+++ b/activity/activity-compose/api/current.txt
@@ -36,7 +36,7 @@
public final class ManagedActivityResultLauncher<I, O> extends androidx.activity.result.ActivityResultLauncher<I> {
method public androidx.activity.result.contract.ActivityResultContract<I,?> getContract();
- method public void launch(I? input, androidx.core.app.ActivityOptionsCompat? options);
+ method public void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
method @Deprecated public void unregister();
}
diff --git a/activity/activity-compose/api/public_plus_experimental_current.txt b/activity/activity-compose/api/public_plus_experimental_current.txt
index ff9df4f..48d220b 100644
--- a/activity/activity-compose/api/public_plus_experimental_current.txt
+++ b/activity/activity-compose/api/public_plus_experimental_current.txt
@@ -36,7 +36,7 @@
public final class ManagedActivityResultLauncher<I, O> extends androidx.activity.result.ActivityResultLauncher<I> {
method public androidx.activity.result.contract.ActivityResultContract<I,?> getContract();
- method public void launch(I? input, androidx.core.app.ActivityOptionsCompat? options);
+ method public void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
method @Deprecated public void unregister();
}
diff --git a/activity/activity-compose/api/restricted_current.ignore b/activity/activity-compose/api/restricted_current.ignore
new file mode 100644
index 0000000..771cee8
--- /dev/null
+++ b/activity/activity-compose/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.compose.ManagedActivityResultLauncher#launch(I, androidx.core.app.ActivityOptionsCompat) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.compose.ManagedActivityResultLauncher.launch(I input, androidx.core.app.ActivityOptionsCompat options)
diff --git a/activity/activity-compose/api/restricted_current.txt b/activity/activity-compose/api/restricted_current.txt
index ff9df4f..48d220b 100644
--- a/activity/activity-compose/api/restricted_current.txt
+++ b/activity/activity-compose/api/restricted_current.txt
@@ -36,7 +36,7 @@
public final class ManagedActivityResultLauncher<I, O> extends androidx.activity.result.ActivityResultLauncher<I> {
method public androidx.activity.result.contract.ActivityResultContract<I,?> getContract();
- method public void launch(I? input, androidx.core.app.ActivityOptionsCompat? options);
+ method public void launch(I input, androidx.core.app.ActivityOptionsCompat? options);
method @Deprecated public void unregister();
}
diff --git a/activity/activity-ktx/api/current.ignore b/activity/activity-ktx/api/current.ignore
new file mode 100644
index 0000000..eabc0b7
--- /dev/null
+++ b/activity/activity-ktx/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, androidx.activity.result.ActivityResultRegistry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
diff --git a/activity/activity-ktx/api/current.txt b/activity/activity-ktx/api/current.txt
index d9a358f..4f387c3 100644
--- a/activity/activity-ktx/api/current.txt
+++ b/activity/activity-ktx/api/current.txt
@@ -15,8 +15,8 @@
package androidx.activity.result {
public final class ActivityResultCallerKt {
- method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
- method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+ method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+ method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
}
public final class ActivityResultKt {
diff --git a/activity/activity-ktx/api/public_plus_experimental_current.txt b/activity/activity-ktx/api/public_plus_experimental_current.txt
index d9a358f..4f387c3 100644
--- a/activity/activity-ktx/api/public_plus_experimental_current.txt
+++ b/activity/activity-ktx/api/public_plus_experimental_current.txt
@@ -15,8 +15,8 @@
package androidx.activity.result {
public final class ActivityResultCallerKt {
- method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
- method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+ method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+ method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
}
public final class ActivityResultKt {
diff --git a/activity/activity-ktx/api/restricted_current.ignore b/activity/activity-ktx/api/restricted_current.ignore
new file mode 100644
index 0000000..eabc0b7
--- /dev/null
+++ b/activity/activity-ktx/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, androidx.activity.result.ActivityResultRegistry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
+InvalidNullConversion: androidx.activity.result.ActivityResultCallerKt#registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O>, I, kotlin.jvm.functions.Function1<? super O,kotlin.Unit>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.ActivityResultCallerKt.registerForActivityResult(androidx.activity.result.ActivityResultCaller arg1, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback)
diff --git a/activity/activity-ktx/api/restricted_current.txt b/activity/activity-ktx/api/restricted_current.txt
index d9a358f..4f387c3 100644
--- a/activity/activity-ktx/api/restricted_current.txt
+++ b/activity/activity-ktx/api/restricted_current.txt
@@ -15,8 +15,8 @@
package androidx.activity.result {
public final class ActivityResultCallerKt {
- method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
- method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I? input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+ method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, androidx.activity.result.ActivityResultRegistry registry, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
+ method public static <I, O> androidx.activity.result.ActivityResultLauncher<kotlin.Unit> registerForActivityResult(androidx.activity.result.ActivityResultCaller, androidx.activity.result.contract.ActivityResultContract<I,O> contract, I input, kotlin.jvm.functions.Function1<? super O,kotlin.Unit> callback);
}
public final class ActivityResultKt {
diff --git a/activity/activity/api/current.ignore b/activity/activity/api/current.ignore
index cd68216..3da4564 100644
--- a/activity/activity/api/current.ignore
+++ b/activity/activity/api/current.ignore
@@ -1,3 +1,13 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallback#onActivityResult(O) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter result in androidx.activity.result.ActivityResultCallback.onActivityResult(O result)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#createIntent(android.content.Context, I) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.createIntent(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#getSynchronousResult(android.content.Context, I) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.getSynchronousResult(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract.SynchronousResult#SynchronousResult(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.activity.result.contract.ActivityResultContract.SynchronousResult(T value)
+
+
RemovedMethod: androidx.activity.ComponentActivity#onBackPressed():
Removed method androidx.activity.ComponentActivity.onBackPressed()
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index 7d61b26..c7520eb 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -176,7 +176,7 @@
}
public fun interface ActivityResultCallback<O> {
- method public void onActivityResult(O? result);
+ method public void onActivityResult(O result);
}
public interface ActivityResultCaller {
@@ -255,15 +255,15 @@
public abstract class ActivityResultContract<I, O> {
ctor public ActivityResultContract();
- method public abstract android.content.Intent createIntent(android.content.Context context, I? input);
- method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I? input);
- method public abstract O! parseResult(int resultCode, android.content.Intent? intent);
+ method public abstract android.content.Intent createIntent(android.content.Context context, I input);
+ method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I input);
+ method public abstract O parseResult(int resultCode, android.content.Intent? intent);
}
public static final class ActivityResultContract.SynchronousResult<T> {
- ctor public ActivityResultContract.SynchronousResult(T? value);
- method public T! getValue();
- property public final T! value;
+ ctor public ActivityResultContract.SynchronousResult(T value);
+ method public T getValue();
+ property public final T value;
}
public final class ActivityResultContracts {
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index 7d61b26..c7520eb 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -176,7 +176,7 @@
}
public fun interface ActivityResultCallback<O> {
- method public void onActivityResult(O? result);
+ method public void onActivityResult(O result);
}
public interface ActivityResultCaller {
@@ -255,15 +255,15 @@
public abstract class ActivityResultContract<I, O> {
ctor public ActivityResultContract();
- method public abstract android.content.Intent createIntent(android.content.Context context, I? input);
- method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I? input);
- method public abstract O! parseResult(int resultCode, android.content.Intent? intent);
+ method public abstract android.content.Intent createIntent(android.content.Context context, I input);
+ method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I input);
+ method public abstract O parseResult(int resultCode, android.content.Intent? intent);
}
public static final class ActivityResultContract.SynchronousResult<T> {
- ctor public ActivityResultContract.SynchronousResult(T? value);
- method public T! getValue();
- property public final T! value;
+ ctor public ActivityResultContract.SynchronousResult(T value);
+ method public T getValue();
+ property public final T value;
}
public final class ActivityResultContracts {
diff --git a/activity/activity/api/restricted_current.ignore b/activity/activity/api/restricted_current.ignore
index cd68216..3da4564 100644
--- a/activity/activity/api/restricted_current.ignore
+++ b/activity/activity/api/restricted_current.ignore
@@ -1,3 +1,13 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.activity.result.ActivityResultCallback#onActivityResult(O) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter result in androidx.activity.result.ActivityResultCallback.onActivityResult(O result)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#createIntent(android.content.Context, I) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.createIntent(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract#getSynchronousResult(android.content.Context, I) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.getSynchronousResult(android.content.Context context, I input)
+InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract.SynchronousResult#SynchronousResult(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.activity.result.contract.ActivityResultContract.SynchronousResult(T value)
+
+
RemovedMethod: androidx.activity.ComponentActivity#onBackPressed():
Removed method androidx.activity.ComponentActivity.onBackPressed()
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index dc7e159..9244450 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -175,7 +175,7 @@
}
public fun interface ActivityResultCallback<O> {
- method public void onActivityResult(O? result);
+ method public void onActivityResult(O result);
}
public interface ActivityResultCaller {
@@ -254,15 +254,15 @@
public abstract class ActivityResultContract<I, O> {
ctor public ActivityResultContract();
- method public abstract android.content.Intent createIntent(android.content.Context context, I? input);
- method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I? input);
- method public abstract O! parseResult(int resultCode, android.content.Intent? intent);
+ method public abstract android.content.Intent createIntent(android.content.Context context, I input);
+ method public androidx.activity.result.contract.ActivityResultContract.SynchronousResult<O>? getSynchronousResult(android.content.Context context, I input);
+ method public abstract O parseResult(int resultCode, android.content.Intent? intent);
}
public static final class ActivityResultContract.SynchronousResult<T> {
- ctor public ActivityResultContract.SynchronousResult(T? value);
- method public T! getValue();
- property public final T! value;
+ ctor public ActivityResultContract.SynchronousResult(T value);
+ method public T getValue();
+ property public final T value;
}
public final class ActivityResultContracts {
diff --git a/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt b/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt
index 1b5036e..6a52ecb 100644
--- a/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt
+++ b/annotation/annotation/src/commonMain/kotlin/androidx/annotation/RestrictTo.kt
@@ -19,20 +19,21 @@
import androidx.annotation.RestrictTo.Scope
/**
- * Denotes that the annotated element should only be accessed from within a
- * specific scope (as defined by [Scope]).
+ * Denotes that the annotated element should only be accessed from within a specific scope (as
+ * defined by [Scope]).
*
- *
- * Example of restricting usage within a library (based on gradle group ID):
+ * Example of restricting usage within a library (based on Gradle group ID):
* ```
* @RestrictTo(GROUP_ID)
* public void resetPaddingToInitialValues() { ...
* ```
+ *
* Example of restricting usage to tests:
* ```
* @RestrictTo(Scope.TESTS)
* public abstract int getUserId();
* ```
+ *
* Example of restricting usage to subclasses:
* ```
* @RestrictTo(Scope.SUBCLASSES)
@@ -53,56 +54,62 @@
)
public expect annotation class RestrictTo(
/**
- * The scope to which usage should be restricted.
+ * The scope(s) to which usage should be restricted.
*/
vararg val value: Scope
) {
public enum class Scope {
/**
- * Restrict usage to code within the same library (e.g. the same
- * gradle group ID and artifact ID).
+ * Restrict usage to code within the same library (e.g. the same Gradle group ID and
+ * artifact ID).
*/
LIBRARY,
/**
* Restrict usage to code within the same group of libraries.
- * This corresponds to the gradle group ID.
+ *
+ * This corresponds to the Gradle group ID.
*/
LIBRARY_GROUP,
/**
- * Restrict usage to code within packages whose groups share
- * the same library group prefix up to the last ".", so for
- * example libraries foo.bar:lib1 and foo.baz:lib2 share
- * the prefix "foo." and so they can use each other's
- * apis that are restricted to this scope. Similarly for
- * com.foo.bar:lib1 and com.foo.baz:lib2 where they share
- * "com.foo.". Library com.bar.qux:lib3 however will not
- * be able to use the restricted api because it only
- * shares the prefix "com." and not all the way until the
- * last ".".
+ * Restrict usage to code within packages whose Gradle group IDs share the same prefix up to
+ * the last `.` separator.
+ *
+ * For example, libraries `foo.bar:lib1` and `foo.baz:lib2` share the `foo.` prefix and can
+ * therefore use each other's APIs that are restricted to this scope. Similar applies to
+ * libraries `com.foo.bar:lib1` and `com.foo.baz:lib2`, which share the `com.foo.` prefix.
+ *
+ * Library `com.bar.qux:lib3`, however, will not be able to use the restricted API because
+ * it only shares the prefix `com.` and not all the way until the last `.` separator.
*/
LIBRARY_GROUP_PREFIX,
/**
- * Restrict usage to code within the same group ID (based on gradle
- * group ID). This is an alias for [LIBRARY_GROUP_PREFIX].
+ * Restrict usage to code within the same group ID (based on Gradle group ID).
*
- * @deprecated Use [LIBRARY_GROUP_PREFIX] instead
+ * This is an alias for [LIBRARY_GROUP_PREFIX].
*/
- @Deprecated("Use LIBRARY_GROUP_PREFIX instead.")
+ @Deprecated(
+ message = "Use @RestrictTo(LIBRARY_GROUP_PREFIX) instead",
+ replaceWith = ReplaceWith(
+ "LIBRARY_GROUP_PREFIX",
+ "androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX"
+ )
+ )
GROUP_ID,
/**
- * Restrict usage to tests.
+ * Restrict usage to test source sets or code annotated with the [TESTS] restriction scope.
+ *
+ * This is equivalent to `@VisibleForTesting(NONE)`.
*/
TESTS,
/**
* Restrict usage to subclasses of the enclosing class.
*
- * **Note:** This scope should not be used to annotate
- * packages.
+ * **Note:** This scope should not be used to annotate packages.
*/
SUBCLASSES,
}
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
index af8360c..5b1fdc6 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
@@ -16,6 +16,10 @@
package androidx.appactions.interaction.capabilities.communication
+import androidx.appactions.builtintypes.experimental.properties.Participant
+import androidx.appactions.builtintypes.experimental.types.Call
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.CapabilityFactory
@@ -27,11 +31,6 @@
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.PARTICIPANT_TYPE_SPEC
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.Call
-import androidx.appactions.interaction.capabilities.core.values.Call.CallFormat
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
@@ -87,7 +86,7 @@
// TODO(b/268369632): Remove Property from public capability APIs.
class Properties
internal constructor(
- val callFormat: Property<CallFormat>?,
+ val callFormat: Property<Call.CanonicalValue.CallFormat>?,
val participant: Property<Participant>?
) {
override fun toString(): String {
@@ -113,13 +112,14 @@
}
class Builder {
- private var callFormat: Property<CallFormat>? = null
+ private var callFormat: Property<Call.CanonicalValue.CallFormat>? = null
private var participant: Property<Participant>? = null
- fun setCallFormat(callFormat: Property<CallFormat>): Builder = apply {
- this.callFormat = callFormat
- }
+ fun setCallFormat(callFormat: Property<Call.CanonicalValue.CallFormat>): Builder =
+ apply {
+ this.callFormat = callFormat
+ }
fun build(): Properties = Properties(callFormat, participant)
}
@@ -127,7 +127,7 @@
class Arguments
internal constructor(
- val callFormat: CallFormat?,
+ val callFormat: Call.CanonicalValue.CallFormat?,
val participantList: List<ParticipantValue>,
) {
override fun toString(): String {
@@ -153,10 +153,10 @@
}
class Builder : BuilderOf<Arguments> {
- private var callFormat: CallFormat? = null
+ private var callFormat: Call.CanonicalValue.CallFormat? = null
private var participantList: List<ParticipantValue> = mutableListOf()
- fun setCallFormat(callFormat: CallFormat): Builder = apply {
+ fun setCallFormat(callFormat: Call.CanonicalValue.CallFormat): Builder = apply {
this.callFormat = callFormat
}
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
index 6f428e1..d2b8b20 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
@@ -16,6 +16,11 @@
package androidx.appactions.interaction.capabilities.communication
+import androidx.appactions.builtintypes.experimental.properties.Recipient
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
+import androidx.appactions.builtintypes.experimental.types.Message
+
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.CapabilityFactory
@@ -28,10 +33,6 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.StringValue
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.Message
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
index c8e6e41..a367315 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
@@ -15,11 +15,11 @@
*/
package androidx.appactions.interaction.capabilities.communication
+import androidx.appactions.builtintypes.experimental.properties.Participant
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant
class ParticipantValue private constructor(
val asParticipant: Participant?,
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
index a91015c..ee21e47 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
@@ -16,11 +16,11 @@
package androidx.appactions.interaction.capabilities.communication
+import androidx.appactions.builtintypes.experimental.properties.Recipient
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient
class RecipientValue private constructor(
val asRecipient: Recipient?,
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt
index d4234c3..5ebbc27 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Attendee.kt
@@ -25,4 +25,11 @@
class Attendee(person: Person) {
@get:JvmName("asPerson")
val asPerson: Person? = person
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is Attendee) return false
+ if (asPerson != other.asPerson) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt
index ea9c33a..5c36634 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/EndDate.kt
@@ -17,7 +17,21 @@
package androidx.appactions.builtintypes.experimental.properties
import java.time.LocalDate
+import java.time.ZonedDateTime
-class EndDate(localDate: LocalDate) {
- val localDate: LocalDate? = localDate
+class EndDate internal constructor(
+ @get:JvmName("asDate")
+ val asDate: LocalDate? = null,
+ @get:JvmName("asZonedDateTime")
+ val asZonedDateTime: ZonedDateTime? = null
+) {
+ constructor(date: LocalDate) : this(asDate = date, asZonedDateTime = null)
+ constructor(zonedDateTime: ZonedDateTime) : this(asDate = null, asZonedDateTime = zonedDateTime)
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is EndDate) return false
+ if (asDate != other.asDate) return false
+ if (asZonedDateTime != other.asZonedDateTime) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt
index 395c1bf..8f7803c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/ItemListElement.kt
@@ -21,4 +21,11 @@
class ItemListElement(asListItem: ListItem) {
@get:JvmName("asListItem")
val asListItem: ListItem = asListItem
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is ItemListElement) return false
+ if (asListItem != other.asListItem) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt
index 7327971..b779c3d 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Name.kt
@@ -19,4 +19,11 @@
class Name(asText: String) {
@get:JvmName("asText")
val asText: String = asText
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is Name) return false
+ if (asText != other.asText) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt
index b84d253..abb312b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Participant.kt
@@ -25,4 +25,10 @@
class Participant(person: Person) {
@get:JvmName("asPerson")
val asPerson: Person? = person
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is Participant) return false
+ if (asPerson != other.asPerson) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt
index d5a9a01..7663eb4 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/Recipient.kt
@@ -25,4 +25,11 @@
class Recipient(person: Person) {
@get:JvmName("asPerson")
val asPerson: Person? = person
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is Recipient) return false
+ if (asPerson != other.asPerson) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt
index 96d54eae..4328dd8 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/properties/StartDate.kt
@@ -17,7 +17,22 @@
package androidx.appactions.builtintypes.experimental.properties
import java.time.LocalDate
+import java.time.ZonedDateTime
-class StartDate(localDate: LocalDate) {
- val localDate: LocalDate? = localDate
+class StartDate internal constructor(
+ @get:JvmName("asDate")
+ val asDate: LocalDate? = null,
+ @get:JvmName("asZonedDateTime")
+ val asZonedDateTime: ZonedDateTime? = null
+) {
+ constructor(date: LocalDate) : this(asDate = date, asZonedDateTime = null)
+ constructor(zonedDateTime: ZonedDateTime) : this(asDate = null, asZonedDateTime = zonedDateTime)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is StartDate) return false
+ if (asDate != other.asDate) return false
+ if (asZonedDateTime != other.asZonedDateTime) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
index 8545b7f..fa8d0d8 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
@@ -22,6 +22,7 @@
import androidx.appactions.builtintypes.experimental.properties.StartDate
import androidx.appactions.builtintypes.experimental.properties.Attendee
import java.time.LocalDate
+import java.time.ZonedDateTime
interface CalendarEvent : Thing {
val startDate: StartDate?
@@ -37,8 +38,10 @@
interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
fun setStartDate(startDate: StartDate?): Self
fun setStartDate(value: LocalDate): Self
+ fun setStartDate(value: ZonedDateTime): Self
fun setEndDate(endDate: EndDate?): Self
fun setEndDate(value: LocalDate): Self
+ fun setEndDate(value: ZonedDateTime): Self
fun addAttendee(attendee: Attendee): Self
fun addAttendees(value: List<Attendee>): Self
@@ -65,6 +68,10 @@
startDate = StartDate(value)
}
+ override fun setStartDate(value: ZonedDateTime): CalendarEventBuilderImpl = apply {
+ startDate = StartDate(value)
+ }
+
override fun setEndDate(endDate: EndDate?): CalendarEventBuilderImpl = apply {
this.endDate = endDate
}
@@ -73,6 +80,10 @@
endDate = EndDate(value)
}
+ override fun setEndDate(value: ZonedDateTime): CalendarEventBuilderImpl = apply {
+ endDate = EndDate(value)
+ }
+
override fun addAttendee(attendee: Attendee): CalendarEventBuilderImpl = apply {
attendeeList.add(attendee)
}
@@ -106,4 +117,16 @@
.setStartDate(startDate)
.setEndDate(endDate)
.addAttendees(attendeeList)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is CalendarEventImpl) return false
+ if (attendeeList != other.attendeeList) return false
+ if (endDate != other.endDate) return false
+ if (startDate != other.startDate) return false
+ if (identifier != other.identifier) return false
+ if (name != other.name) return false
+
+ return true
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
index 4d5eecd..e2308b6 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
@@ -81,4 +81,13 @@
.setIdentifier(identifier)
.setName(name)
.addItemListElements(itemListElements)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is ItemListImpl) return false
+ if (this.name != other.name) return false
+ if (this.identifier != other.identifier) return false
+ if (this.itemListElements != other.itemListElements) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt
index 4c199e0..65b4845 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ListItem.kt
@@ -57,4 +57,12 @@
) : ListItem {
override fun toBuilder(): ListItem.Builder<*> =
ListItemBuilderImpl().setIdentifier(identifier).setName(name)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is ListItemImpl) return false
+ if (this.name != other.name) return false
+ if (this.identifier != other.identifier) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt
index 6e92203..62a5892 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Person.kt
@@ -72,4 +72,14 @@
.setName(name)
.setEmail(email)
.setTelephone(telephone)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is PersonImpl) return false
+ if (email != other.email) return false
+ if (telephone != other.telephone) return false
+ if (identifier != other.identifier) return false
+ if (name != other.name) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt
index ecdd7e8..1051242 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Thing.kt
@@ -53,9 +53,25 @@
override fun setName(text: String): ThingBuilderImpl = apply { name = Name(text) }
override fun setName(name: Name?): ThingBuilderImpl = apply { this.name = name }
override fun clearName(): ThingBuilderImpl = apply { name = null }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+
+ other as ThingBuilderImpl
+ if (this.name != other.name) return false
+ if (this.identifier != other.identifier) return false
+ return true
+ }
}
private class ThingImpl(override val identifier: String?, override val name: Name?) : Thing {
override fun toBuilder(): Thing.Builder<*> =
ThingBuilderImpl().setIdentifier(identifier).setName(name)
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is ThingImpl) return false
+ if (this.name != other.name) return false
+ if (this.identifier != other.identifier) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt
index afe2dba..b90d44b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/Timer.kt
@@ -50,4 +50,12 @@
private class TimerImpl(override val identifier: String?, override val name: Name?) : Timer {
override fun toBuilder(): Timer.Builder<*> =
TimerBuilderImpl().setIdentifier(identifier).setName(name)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is TimerImpl) return false
+ if (identifier != other.identifier) return false
+ if (name != other.name) return false
+ return true
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
index c3fcad0..5433788 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
@@ -24,7 +24,7 @@
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpec
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.Thing
+import androidx.appactions.builtintypes.experimental.types.Thing
import androidx.appactions.interaction.proto.GroundingRequest
import androidx.appactions.interaction.proto.GroundingResponse
import androidx.concurrent.futures.await
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt
index 3c50190..df74750 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/ParamValueConverter.kt
@@ -38,6 +38,7 @@
* @param typeSpec the TypeSpec of the structured type, which can
* read/write objects to/from Struct.
*/
+ @JvmStatic
fun <T> of(typeSpec: TypeSpec<T>) = object : ParamValueConverter<T> {
override fun fromParamValue(paramValue: ParamValue): T {
return typeSpec.fromValue(paramValueToValue(paramValue))
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java
index d1af888..20ef55b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/SlotTypeConverter.java
@@ -17,6 +17,7 @@
package androidx.appactions.interaction.capabilities.core.impl.converters;
import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
import androidx.appactions.interaction.proto.ParamValue;
@@ -30,6 +31,7 @@
* @param <T>
*/
@FunctionalInterface
+@RestrictTo(RestrictTo.Scope.LIBRARY)
public interface SlotTypeConverter<T> {
@NonNull
static <T> SlotTypeConverter<List<T>> ofRepeated(
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
index 60082a6..34f1ddc 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
@@ -17,22 +17,23 @@
package androidx.appactions.interaction.capabilities.core.impl.converters;
import androidx.annotation.NonNull;
+import androidx.appactions.builtintypes.experimental.properties.Attendee;
+import androidx.appactions.builtintypes.experimental.properties.ItemListElement;
+import androidx.appactions.builtintypes.experimental.properties.Participant;
+import androidx.appactions.builtintypes.experimental.properties.Recipient;
+import androidx.appactions.builtintypes.experimental.types.Alarm;
+import androidx.appactions.builtintypes.experimental.types.CalendarEvent;
+import androidx.appactions.builtintypes.experimental.types.Call;
+import androidx.appactions.builtintypes.experimental.types.ItemList;
+import androidx.appactions.builtintypes.experimental.types.ListItem;
+import androidx.appactions.builtintypes.experimental.types.Message;
+import androidx.appactions.builtintypes.experimental.types.Person;
+import androidx.appactions.builtintypes.experimental.types.SafetyCheck;
+import androidx.appactions.builtintypes.experimental.types.Timer;
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-import androidx.appactions.interaction.capabilities.core.values.Alarm;
-import androidx.appactions.interaction.capabilities.core.values.CalendarEvent;
-import androidx.appactions.interaction.capabilities.core.values.Call;
import androidx.appactions.interaction.capabilities.core.values.EntityValue;
-import androidx.appactions.interaction.capabilities.core.values.ItemList;
-import androidx.appactions.interaction.capabilities.core.values.ListItem;
-import androidx.appactions.interaction.capabilities.core.values.Message;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-import androidx.appactions.interaction.capabilities.core.values.SafetyCheck;
import androidx.appactions.interaction.capabilities.core.values.SearchAction;
-import androidx.appactions.interaction.capabilities.core.values.Timer;
-import androidx.appactions.interaction.capabilities.core.values.properties.Attendee;
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant;
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient;
import androidx.appactions.interaction.proto.Entity;
import androidx.appactions.interaction.proto.ParamValue;
@@ -42,94 +43,136 @@
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
+import java.util.Optional;
/** Converters for capability argument values. Convert from internal proto types to public types. */
public final class TypeConverters {
public static final String FIELD_NAME_TYPE = "@type";
public static final TypeSpec<ListItem> LIST_ITEM_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("ListItem", ListItem::newBuilder).build();
- public static final TypeSpec<ItemList> ITEM_LIST_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("ItemList", ItemList::newBuilder)
- .bindRepeatedSpecField(
- "itemListElement",
- ItemList::getListItems,
- ItemList.Builder::addAllListItems,
+ TypeSpecBuilder.newBuilderForThing(
+ "ListItem",
+ ListItem::Builder,
+ ListItem.Builder::build).build();
+ public static final TypeSpec<ItemListElement> ITEM_LIST_ELEMENT_TYPE_SPEC =
+ new UnionTypeSpec.Builder<ItemListElement>()
+ .bindMemberType(
+ ItemListElement::asListItem,
+ ItemListElement::new,
LIST_ITEM_TYPE_SPEC)
.build();
+ public static final TypeSpec<ItemList> ITEM_LIST_TYPE_SPEC =
+ TypeSpecBuilder.newBuilderForThing(
+ "ItemList",
+ ItemList::Builder,
+ ItemList.Builder::build)
+ .bindRepeatedSpecField(
+ "itemListElement",
+ ItemList::getItemListElements,
+ ItemList.Builder::addItemListElements,
+ ITEM_LIST_ELEMENT_TYPE_SPEC)
+ .build();
+
public static final TypeSpec<Person> PERSON_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("Person", Person::newBuilder)
- .bindStringField("email", Person::getEmail, Person.Builder::setEmail)
+ TypeSpecBuilder.newBuilderForThing(
+ "Person",
+ Person::Builder,
+ Person.Builder::build)
+ .bindStringField("email",
+ person -> Optional.ofNullable(person.getEmail()),
+ Person.Builder::setEmail)
.bindStringField(
- "telephone", Person::getTelephone, Person.Builder::setTelephone)
- .bindStringField("name", Person::getName, Person.Builder::setName)
+ "telephone",
+ person -> Optional.ofNullable(person.getTelephone()),
+ Person.Builder::setTelephone)
+ .bindStringField("name",
+ person -> Optional.ofNullable(person.getName())
+ .flatMap(name -> Optional.ofNullable(name.asText())),
+ Person.Builder::setName)
.build();
public static final TypeSpec<Alarm> ALARM_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("Alarm", Alarm::newBuilder).build();
+ TypeSpecBuilder.newBuilderForThing(
+ "Alarm", Alarm::Builder, Alarm.Builder::build).build();
public static final TypeSpec<Timer> TIMER_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("Timer", Timer::newBuilder).build();
+ TypeSpecBuilder.newBuilderForThing(
+ "Timer", Timer::Builder, Timer.Builder::build).build();
public static final TypeSpec<Attendee> ATTENDEE_TYPE_SPEC =
new UnionTypeSpec.Builder<Attendee>()
.bindMemberType(
- (attendee) -> attendee.asPerson().orElse(null),
+ Attendee::asPerson,
Attendee::new,
PERSON_TYPE_SPEC)
.build();
public static final TypeSpec<CalendarEvent> CALENDAR_EVENT_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("CalendarEvent", CalendarEvent::newBuilder)
+ TypeSpecBuilder.newBuilderForThing(
+ "CalendarEvent",
+ CalendarEvent::Builder,
+ CalendarEvent.Builder::build)
.bindZonedDateTimeField(
"startDate",
- CalendarEvent::getStartDate,
+ calendarEvent -> Optional.ofNullable(
+ calendarEvent.getStartDate().asZonedDateTime()),
CalendarEvent.Builder::setStartDate)
.bindZonedDateTimeField(
- "endDate", CalendarEvent::getEndDate, CalendarEvent.Builder::setEndDate)
+ "endDate",
+ calendarEvent -> Optional.ofNullable(
+ calendarEvent.getEndDate().asZonedDateTime()),
+ CalendarEvent.Builder::setEndDate)
.bindRepeatedSpecField(
"attendee",
CalendarEvent::getAttendeeList,
- CalendarEvent.Builder::addAllAttendee,
+ CalendarEvent.Builder::addAttendees,
ATTENDEE_TYPE_SPEC)
.build();
public static final TypeSpec<SafetyCheck> SAFETY_CHECK_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("SafetyCheck", SafetyCheck::newBuilder)
+ TypeSpecBuilder.newBuilderForThing(
+ "SafetyCheck",
+ SafetyCheck::Builder,
+ SafetyCheck.Builder::build)
.bindDurationField(
- "duration", SafetyCheck::getDuration, SafetyCheck.Builder::setDuration)
+ "duration",
+ safetyCheck -> Optional.ofNullable(safetyCheck.getDuration()),
+ SafetyCheck.Builder::setDuration)
.bindZonedDateTimeField(
- "checkinTime",
- SafetyCheck::getCheckinTime,
- SafetyCheck.Builder::setCheckinTime)
+ "checkInTime",
+ safetyCheck -> Optional.ofNullable(safetyCheck.getCheckInTime()),
+ SafetyCheck.Builder::setCheckInTime)
.build();
public static final TypeSpec<Recipient> RECIPIENT_TYPE_SPEC =
new UnionTypeSpec.Builder<Recipient>()
.bindMemberType(
- (recipient) -> recipient.asPerson().orElse(null),
+ Recipient::asPerson,
Recipient::new,
PERSON_TYPE_SPEC)
.build();
public static final TypeSpec<Participant> PARTICIPANT_TYPE_SPEC =
new UnionTypeSpec.Builder<Participant>()
.bindMemberType(
- (participant) -> participant.asPerson().orElse(null),
+ Participant::asPerson,
Participant::new,
PERSON_TYPE_SPEC)
.build();
public static final TypeSpec<Message> MESSAGE_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("Message", Message::newBuilder)
- .bindIdentifier(Message::getId)
+ TypeSpecBuilder.newBuilderForThing(
+ "Message",
+ Message::Builder,
+ Message.Builder::build)
+ .bindIdentifier(message -> Optional.ofNullable(message.getIdentifier()))
.bindRepeatedSpecField(
"recipient",
Message::getRecipientList,
- Message.Builder::addAllRecipient,
+ Message.Builder::addRecipients,
RECIPIENT_TYPE_SPEC)
.bindStringField(
- "text", Message::getMessageText, Message.Builder::setMessageText)
+ "text",
+ message -> Optional.of(message.getText().asText()),
+ Message.Builder::setText)
.build();
public static final TypeSpec<Call> CALL_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing("Call", Call::newBuilder)
- .bindIdentifier(Call::getId)
- .bindEnumField(
- "callFormat",
- Call::getCallFormat,
- Call.Builder::setCallFormat,
- Call.CallFormat.class)
+ TypeSpecBuilder.newBuilderForThing(
+ "Call",
+ Call::Builder,
+ Call.Builder::build)
+ .bindIdentifier(call -> Optional.ofNullable(call.getIdentifier()))
.bindRepeatedSpecField(
"participant",
Call::getParticipantList,
@@ -138,42 +181,11 @@
.build();
public static final ParamValueConverter<Integer> INTEGER_PARAM_VALUE_CONVERTER =
- new ParamValueConverter<Integer>() {
- @NonNull
- @Override
- public ParamValue toParamValue(Integer value) {
- return ParamValue.newBuilder().setNumberValue(value * 1.0).build();
- }
+ ParamValueConverter.of(TypeSpec.INTEGER_TYPE_SPEC);
- @Override
- public Integer fromParamValue(@NonNull ParamValue paramValue)
- throws StructConversionException {
- if (paramValue.hasNumberValue()) {
- return (int) paramValue.getNumberValue();
- }
- throw new StructConversionException(
- "Cannot parse integer because number_value"
- + " is missing from ParamValue.");
- }
- };
public static final ParamValueConverter<Boolean> BOOLEAN_PARAM_VALUE_CONVERTER =
- new ParamValueConverter<Boolean>() {
- @NonNull
- @Override
- public ParamValue toParamValue(Boolean value) {
- return ParamValue.newBuilder().setBoolValue(value).build();
- }
+ ParamValueConverter.of(TypeSpec.BOOL_TYPE_SPEC);
- @Override
- public Boolean fromParamValue(@NonNull ParamValue paramValue)
- throws StructConversionException {
- if (paramValue.hasBoolValue()) {
- return paramValue.getBoolValue();
- }
- throw new StructConversionException(
- "Cannot parse boolean because bool_value is missing from ParamValue.");
- }
- };
public static final ParamValueConverter<EntityValue> ENTITY_PARAM_VALUE_CONVERTER =
new ParamValueConverter<EntityValue>() {
@NonNull
@@ -194,21 +206,8 @@
}
};
public static final ParamValueConverter<String> STRING_PARAM_VALUE_CONVERTER =
- new ParamValueConverter<String>() {
- @NonNull
- @Override
- public ParamValue toParamValue(String value) {
- return ParamValue.newBuilder().setStringValue(value).build();
- }
+ ParamValueConverter.of(TypeSpec.STRING_TYPE_SPEC);
- @Override
- public String fromParamValue(@NonNull ParamValue paramValue) {
- if (paramValue.hasIdentifier()) {
- return paramValue.getIdentifier();
- }
- return paramValue.getStringValue();
- }
- };
public static final ParamValueConverter<LocalDate> LOCAL_DATE_PARAM_VALUE_CONVERTER =
new ParamValueConverter<LocalDate>() {
@NonNull
@@ -331,30 +330,33 @@
}
}
};
- public static final ParamValueConverter<Call.CallFormat> CALL_FORMAT_PARAM_VALUE_CONVERTER =
- new ParamValueConverter<Call.CallFormat>() {
+ public static final ParamValueConverter<Call.CanonicalValue.CallFormat>
+ CALL_FORMAT_PARAM_VALUE_CONVERTER =
+ new ParamValueConverter<Call.CanonicalValue.CallFormat>() {
+
@NonNull
@Override
- public ParamValue toParamValue(Call.CallFormat value) {
+ public ParamValue toParamValue(Call.CanonicalValue.CallFormat value) {
// TODO(b/275456249)): Implement backwards conversion.
return ParamValue.getDefaultInstance();
}
@Override
- public Call.CallFormat fromParamValue(@NonNull ParamValue paramValue)
+ public Call.CanonicalValue.CallFormat fromParamValue(@NonNull ParamValue paramValue)
throws StructConversionException {
String identifier = paramValue.getIdentifier();
- if (identifier.equals(Call.CallFormat.AUDIO.toString())) {
- return Call.CallFormat.AUDIO;
- } else if (identifier.equals(Call.CallFormat.VIDEO.toString())) {
- return Call.CallFormat.VIDEO;
+ if (identifier.equals(Call.CanonicalValue.CallFormat.Audio.getTextValue())) {
+ return Call.CanonicalValue.CallFormat.Audio;
+ } else if (identifier.equals(
+ Call.CanonicalValue.CallFormat.Video.getTextValue())) {
+ return Call.CanonicalValue.CallFormat.Video;
}
throw new StructConversionException(
String.format("Unknown enum format '%s'.", identifier));
}
};
public static final EntityConverter<
- androidx.appactions.interaction.capabilities.core.properties.Entity>
+ androidx.appactions.interaction.capabilities.core.properties.Entity>
ENTITY_ENTITY_CONVERTER =
(entity) -> {
Entity.Builder builder =
@@ -382,15 +384,16 @@
(localTime) -> Entity.newBuilder().setStringValue(localTime.toString()).build();
public static final EntityConverter<Duration> DURATION_ENTITY_CONVERTER =
(duration) -> Entity.newBuilder().setStringValue(duration.toString()).build();
- public static final EntityConverter<Call.CallFormat> CALL_FORMAT_ENTITY_CONVERTER =
- (callFormat) -> Entity.newBuilder().setIdentifier(callFormat.toString()).build();
+ public static final EntityConverter<Call.CanonicalValue.CallFormat>
+ CALL_FORMAT_ENTITY_CONVERTER =
+ (callFormat) ->
+ Entity.newBuilder().setIdentifier(callFormat.getTextValue()).build();
- private TypeConverters() {}
+ private TypeConverters() {
+ }
/**
- * @param nestedTypeSpec
- * @param <T>
- * @return
+ *
*/
@NonNull
public static <T> TypeSpec<SearchAction<T>> createSearchActionTypeSpec(
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
index ff9b0e3..fbb5d4a 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpec.kt
@@ -38,6 +38,7 @@
fun fromValue(value: Value): T
companion object {
+ @JvmField
val STRING_TYPE_SPEC = object : TypeSpec<String> {
override fun getIdentifier(obj: String): String? = null
@@ -51,6 +52,7 @@
}
}
+ @JvmField
val BOOL_TYPE_SPEC = object : TypeSpec<Boolean> {
override fun getIdentifier(obj: Boolean): String? = null
@@ -64,6 +66,7 @@
}
}
+ @JvmField
val NUMBER_TYPE_SPEC = object : TypeSpec<Double> {
override fun getIdentifier(obj: Double): String? = null
@@ -77,6 +80,7 @@
}
}
+ @JvmField
val INTEGER_TYPE_SPEC = object : TypeSpec<Int> {
override fun getIdentifier(obj: Int): String? = null
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
index 7b03d72..f8ea421 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
@@ -18,9 +18,9 @@
import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
+import androidx.appactions.builtintypes.experimental.types.Thing;
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
import androidx.appactions.interaction.protobuf.ListValue;
import androidx.appactions.interaction.protobuf.Struct;
import androidx.appactions.interaction.protobuf.Value;
@@ -80,7 +80,7 @@
* StructConversionException.
*
* @param struct the Struct to get values from.
- * @param key the String key of the field to retrieve.
+ * @param key the String key of the field to retrieve.
*/
private static Value getFieldFromStruct(Struct struct, String key)
throws StructConversionException {
@@ -98,26 +98,11 @@
}
/**
- * Creates a new TypeSpecBuilder for a child class of Thing.
- *
- * <p>Comes with bindings for Thing fields.
- */
- static <T extends Thing, BuilderT extends Thing.Builder<BuilderT> & BuilderOf<T>>
- TypeSpecBuilder<T, BuilderT> newBuilderForThing(
- String typeName, Supplier<BuilderT> builderSupplier) {
- return newBuilder(typeName, builderSupplier)
- .bindIdentifier(T::getId)
- .bindStringField("identifier", T::getId, BuilderT::setId)
- .bindStringField("name", T::getName, BuilderT::setName);
- }
-
- /**
* Creates a new TypeSpecBuilder for a child class of Thing (temporary BuiltInTypes).
*
* <p>Comes with bindings for Thing fields.
*/
- static <T extends androidx.appactions.builtintypes.experimental.types.Thing,
- BuilderT extends androidx.appactions.builtintypes.experimental.types.Thing.Builder<?>>
+ static <T extends Thing, BuilderT extends Thing.Builder<?>>
TypeSpecBuilder<T, BuilderT> newBuilderForThing(
String typeName,
Supplier<BuilderT> builderSupplier,
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Alarm.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Alarm.java
deleted file mode 100644
index ca545f1..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Alarm.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents a single item in an item list. */
-@AutoValue
-public abstract class Alarm extends Thing {
-
- /** Create a new Alarm instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_Alarm.Builder();
- }
-
- /** Builder class for Alarm entities. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder> implements
- BuilderOf<Alarm> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/CalendarEvent.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/CalendarEvent.java
deleted file mode 100644
index d35dcf1..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/CalendarEvent.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.properties.Attendee;
-
-import com.google.auto.value.AutoValue;
-
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/** Represents a CalendarEvent. */
-@SuppressWarnings("AutoValueImmutableFields")
-@AutoValue
-public abstract class CalendarEvent extends Thing {
- /** Create a new CalendarEvent.Builder instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_CalendarEvent.Builder();
- }
-
- /** Returns the start date. */
- @NonNull
- public abstract Optional<ZonedDateTime> getStartDate();
-
- /** Returns the end date. */
- @NonNull
- public abstract Optional<ZonedDateTime> getEndDate();
-
- /** Returns the {@link Attendee}s in the CalendarEvent. */
- @NonNull
- public abstract List<Attendee> getAttendeeList();
-
- /** Builder class for building a CalendarEvent. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<CalendarEvent> {
-
- private final List<Attendee> mAttendeeList = new ArrayList<>();
-
- /** Sets start date. */
- @NonNull
- public abstract Builder setStartDate(@NonNull ZonedDateTime startDate);
-
- /** Sets end date. */
- @NonNull
- public abstract Builder setEndDate(@NonNull ZonedDateTime endDate);
-
- /** Adds a person. */
- @NonNull
- public final Builder addAttendee(@NonNull Person person) {
- mAttendeeList.add(new Attendee(person));
- return this;
- }
-
- /** Adds a Attendee. */
- @NonNull
- public final Builder addAttendee(@NonNull Attendee attendee) {
- mAttendeeList.add(attendee);
- return this;
- }
-
- /** Add a list of attendees. */
- @NonNull
- public final Builder addAllAttendee(@NonNull Iterable<Attendee> attendees) {
- for (Attendee attendee : attendees) {
- mAttendeeList.add(attendee);
- }
- return this;
- }
-
- /** Add a list of persons. */
- @NonNull
- public final Builder addAllPerson(@NonNull Iterable<Person> persons) {
- for (Person person : persons) {
- mAttendeeList.add(new Attendee(person));
- }
- return this;
- }
-
- /** Builds and returns the CalendarEvent instance. */
- @Override
- @NonNull
- public final CalendarEvent build() {
- setAttendeeList(mAttendeeList);
- return autoBuild();
- }
-
- /** Sets the attendees of the CalendarEvent. */
- @NonNull
- abstract Builder setAttendeeList(@NonNull List<Attendee> attendeeList);
-
- @NonNull
- abstract CalendarEvent autoBuild();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Call.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Call.java
deleted file mode 100644
index 5698873..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Call.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/** Represents a Call. */
-@AutoValue
-public abstract class Call extends Thing {
- /** Create a new Call.Builder instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_Call.Builder();
- }
-
- /** Returns the call format, e.g. video or audio. */
- @NonNull
- public abstract Optional<CallFormat> getCallFormat();
-
- /** Returns the {@link Participant}s in the call. */
- @NonNull
- @SuppressWarnings("AutoValueImmutableFields")
- public abstract List<Participant> getParticipantList();
-
- /** Format of the call. */
- public enum CallFormat {
- AUDIO("Audio"),
- VIDEO("Video");
-
- private final String mCallFormat;
-
- CallFormat(String callFormat) {
- this.mCallFormat = callFormat;
- }
-
- @Override
- public String toString() {
- return mCallFormat;
- }
- }
-
- /** Builder class for building a Call. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder> implements BuilderOf<Call> {
-
- private final List<Participant> mParticipantList = new ArrayList<>();
-
- /** Sets call format. */
- @NonNull
- public abstract Builder setCallFormat(@NonNull CallFormat callFormat);
-
- /** Adds a person. */
- @NonNull
- public final Builder addParticipant(@NonNull Person person) {
- mParticipantList.add(new Participant(person));
- return this;
- }
-
- /** Adds a Participant. */
- @NonNull
- public final Builder addParticipant(@NonNull Participant participant) {
- mParticipantList.add(participant);
- return this;
- }
-
- /** Add a list of participants. */
- @NonNull
- public final Builder addAllParticipant(@NonNull Iterable<Participant> participants) {
- for (Participant participant : participants) {
- mParticipantList.add(participant);
- }
- return this;
- }
-
- /** Add a list of persons. */
- @NonNull
- public final Builder addAllPerson(@NonNull Iterable<Person> persons) {
- for (Person person : persons) {
- mParticipantList.add(new Participant(person));
- }
- return this;
- }
-
- /** Builds and returns the Call instance. */
- @Override
- @NonNull
- public final Call build() {
- setParticipantList(mParticipantList);
- return autoBuild();
- }
-
- /** Sets the participants of the call. */
- @NonNull
- abstract Builder setParticipantList(@NonNull List<Participant> participantList);
-
- @NonNull
- abstract Call autoBuild();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/GenericErrorStatus.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/GenericErrorStatus.java
deleted file mode 100644
index a7c0713..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/GenericErrorStatus.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** GenericErrorStatus for ExecutionStatus. */
-@AutoValue
-public abstract class GenericErrorStatus extends Thing {
-
- /** Create a new GenericErrorStatus instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_GenericErrorStatus.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static GenericErrorStatus getDefaultInstance() {
- return new AutoValue_GenericErrorStatus.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "GenericErrorStatus";
- }
-
- /** Builder class for GenericErrorStatus status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<GenericErrorStatus> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ItemList.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ItemList.java
deleted file mode 100644
index bf0a69f..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ItemList.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/** Represents an ItemList object. */
-@SuppressWarnings("AutoValueImmutableFields")
-@AutoValue
-public abstract class ItemList extends Thing {
-
- /** Create a new ItemList.Builder instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_ItemList.Builder();
- }
-
- /** Returns the optional list items in this ItemList. */
- @NonNull
- public abstract List<ListItem> getListItems();
-
- /** Builder class for building item lists with items. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<ItemList> {
-
- private final List<ListItem> mListItemsToBuild = new ArrayList<>();
-
- /** Add one or more ListItem to the ItemList to be built. */
- @NonNull
- public final Builder addListItem(@NonNull ListItem... listItems) {
- Collections.addAll(mListItemsToBuild, listItems);
- return this;
- }
-
- /** Add a list of ListItem to the ItemList to be built. */
- @NonNull
- public final Builder addAllListItems(@NonNull List<ListItem> listItems) {
- return addListItem(listItems.toArray(new ListItem[0]));
- }
-
- abstract Builder setListItems(List<ListItem> listItems);
-
- /** Builds and returns the ItemList. */
- @Override
- @NonNull
- public final ItemList build() {
- setListItems(Collections.unmodifiableList(mListItemsToBuild));
- return autoBuild();
- }
-
- @NonNull
- abstract ItemList autoBuild();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ListItem.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ListItem.java
deleted file mode 100644
index e79e99f..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/ListItem.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents a single item in an item list. */
-@AutoValue
-public abstract class ListItem extends Thing {
-
- /** Creates a ListItem given its name. */
- @NonNull
- public static ListItem create(@NonNull String id, @NonNull String name) {
- return newBuilder().setId(id).setName(name).build();
- }
-
- /** Create a new ListItem.Builder instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_ListItem.Builder();
- }
-
- /** Builder class for building item lists with items. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<ListItem> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Message.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Message.java
deleted file mode 100644
index 7e5d875..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Message.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/** Represents an message object. */
-@SuppressWarnings("AutoValueImmutableFields")
-@AutoValue
-public abstract class Message extends Thing {
-
- /** Create a new Message.Builder instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_Message.Builder();
- }
-
- /** Returns the recipients of the message. */
- @NonNull
- public abstract List<Recipient> getRecipientList();
-
- /** Returns the message text. */
- @NonNull
- public abstract Optional<String> getMessageText();
-
- /** Builder class for building an Message. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<Message> {
-
- private final List<Recipient> mRecipientList = new ArrayList<>();
-
- /** Adds a {@link Person}. */
- @NonNull
- public final Builder addRecipient(@NonNull Person person) {
- mRecipientList.add(new Recipient(person));
- return this;
- }
-
- /** Adds a {@link Recipient}. */
- @NonNull
- public final Builder addRecipient(@NonNull Recipient recipient) {
- mRecipientList.add(recipient);
- return this;
- }
-
- /** Adds a list of {@link Recipient}s. */
- @NonNull
- public final Builder addAllRecipient(@NonNull Iterable<Recipient> recipients) {
- for (Recipient recipient : recipients) {
- mRecipientList.add(recipient);
- }
- return this;
- }
-
- /** Sets the message text. */
- @NonNull
- public abstract Builder setMessageText(@NonNull String messageText);
-
- /** Builds and returns the Message instance. */
- @Override
- @NonNull
- public final Message build() {
- setRecipientList(mRecipientList);
- return autoBuild();
- }
-
- /** Sets the recipients of the message. */
- @NonNull
- abstract Builder setRecipientList(@NonNull List<Recipient> recipientList);
-
- @NonNull
- abstract Message autoBuild();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Person.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Person.java
deleted file mode 100644
index a54bb59..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Person.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/** Represents a person. */
-@AutoValue
-public abstract class Person extends Thing {
- /** Create a new Person.Builder instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_Person.Builder();
- }
-
- /** Returns the email. */
- @NonNull
- public abstract Optional<String> getEmail();
-
- /** Returns the telephone. */
- @NonNull
- public abstract Optional<String> getTelephone();
-
- /** Builder class for building a Person. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder> implements
- BuilderOf<Person> {
- /** Sets the email. */
- @NonNull
- public abstract Builder setEmail(@NonNull String email);
-
- /** Sets the telephone. */
- @NonNull
- public abstract Builder setTelephone(@NonNull String telephone);
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SafetyCheck.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SafetyCheck.java
deleted file mode 100644
index afe240c..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SafetyCheck.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.time.Duration;
-import java.time.ZonedDateTime;
-import java.util.Optional;
-
-/** Represents a SafetyCheck. */
-@AutoValue
-public abstract class SafetyCheck extends Thing {
- /** Create a new SafetyCheck instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_SafetyCheck.Builder();
- }
-
- /** Returns the duration. */
- @NonNull
- public abstract Optional<Duration> getDuration();
-
- /** Returns the check-in time. */
- @NonNull
- public abstract Optional<ZonedDateTime> getCheckinTime();
-
- /** Builder class for building a SafetyCheck. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<SafetyCheck> {
- @NonNull
- public abstract Builder setDuration(@NonNull Duration duration);
-
- @NonNull
- public abstract Builder setCheckinTime(@NonNull ZonedDateTime checkinTime);
-
- /** Builds and returns the SafetyCheck instance. */
- @Override
- @NonNull
- public final SafetyCheck build() {
- return autoBuild();
- }
-
- @NonNull
- abstract SafetyCheck autoBuild();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SuccessStatus.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SuccessStatus.java
deleted file mode 100644
index af4469a..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/SuccessStatus.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** SuccessStatus for ExecutionStatus. */
-@AutoValue
-public abstract class SuccessStatus extends Thing {
-
- /** Create a new SuccessStatus instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_SuccessStatus.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static SuccessStatus getDefaultInstance() {
- return new AutoValue_SuccessStatus.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "SuccessStatus";
- }
-
- /** Builder class for SuccessStatus status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<SuccessStatus> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Thing.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Thing.java
deleted file mode 100644
index 7d897f0..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Thing.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-
-import java.util.Optional;
-
-/** Common interface for structured entity. */
-public abstract class Thing {
- /** Returns the id of this thing. */
- @NonNull
- public abstract Optional<String> getId();
-
- /** Returns the name of this thing. */
- @NonNull
- public abstract Optional<String> getName();
-
- /**
- * Base builder class that can be extended to build objects that extend Thing.
- *
- * @param <T>
- */
- public abstract static class Builder<T extends Builder<T>> {
- /** Sets the id of the Thing to be built. */
- @NonNull
- public abstract T setId(@NonNull String id);
-
- /** Sets the name of the Thing to be built. */
- @NonNull
- public abstract T setName(@NonNull String name);
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Timer.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Timer.java
deleted file mode 100644
index 80627b4..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/Timer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents a Timer. */
-@AutoValue
-public abstract class Timer extends Thing {
-
- /** Create a new Timer instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_Timer.Builder();
- }
-
- /** Builder class for Timer. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder> implements
- BuilderOf<Timer> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionAlreadyInProgress.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionAlreadyInProgress.java
deleted file mode 100644
index 57fe650..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionAlreadyInProgress.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to the action being in progress. */
-@AutoValue
-public abstract class ActionAlreadyInProgress extends Thing {
-
- /** Create a new ActionAlreadyInProgress instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_ActionAlreadyInProgress.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static ActionAlreadyInProgress getDefaultInstance() {
- return new AutoValue_ActionAlreadyInProgress.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "ActionAlreadyInProgress";
- }
-
- /** Builder class for ActionAlreadyInProgress status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<ActionAlreadyInProgress> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionNotInProgress.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionNotInProgress.java
deleted file mode 100644
index 4b342a6..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/ActionNotInProgress.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to the action not being in progress. */
-@AutoValue
-public abstract class ActionNotInProgress extends Thing {
-
- /** Create a new ActionNotInProgress instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_ActionNotInProgress.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static ActionNotInProgress getDefaultInstance() {
- return new AutoValue_ActionNotInProgress.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "ActionNotInProgress";
- }
-
- /** Builder class for ActionNotInProgress status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<ActionNotInProgress> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/NoInternetConnection.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/NoInternetConnection.java
deleted file mode 100644
index 3a3bb5b..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/executionstatus/NoInternetConnection.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to no internet connection. */
-@AutoValue
-public abstract class NoInternetConnection extends Thing {
-
- /** Create a new NoInternetConnection instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_NoInternetConnection.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static NoInternetConnection getDefaultInstance() {
- return new AutoValue_NoInternetConnection.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "NoInternetConnection";
- }
-
- /** Builder class for NoInternetConnection status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<NoInternetConnection> {
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Attendee.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Attendee.java
deleted file mode 100644
index 1c5ef74..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Attendee.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/**
- * Represents the value of the union property: http://schema.org/attendee, currently it only can
- * contain {@link Person}.
- */
-public class Attendee {
- private final Value mValue;
-
- public Attendee(@NonNull Person person) {
- mValue = new AutoValue_Attendee_Value(Optional.of(person));
- }
-
- @NonNull
- public Optional<Person> asPerson() {
- return mValue.person();
- }
-
- @Override
- public int hashCode() {
- return mValue.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (object instanceof Attendee) {
- Attendee that = (Attendee) object;
- return this.mValue.equals(that.mValue);
- }
- return false;
- }
-
- /** Represents the value in the this wrapper class. */
- @AutoValue
- abstract static class Value {
- abstract Optional<Person> person();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Participant.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Participant.java
deleted file mode 100644
index 02cbc7b..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Participant.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/**
- * Represents the value of the union property: http://schema.org/participant, currently it only can
- * contain {@link Person}.
- */
-public class Participant {
- private final Value mValue;
-
- public Participant(@NonNull Person person) {
- mValue = new AutoValue_Participant_Value(Optional.of(person));
- }
-
- @NonNull
- public Optional<Person> asPerson() {
- return mValue.person();
- }
-
- @Override
- public int hashCode() {
- return mValue.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (object instanceof Participant) {
- Participant that = (Participant) object;
- return this.mValue.equals(that.mValue);
- }
- return false;
- }
-
- /** Represents the value in the this wrapper class. */
- @AutoValue
- abstract static class Value {
- abstract Optional<Person> person();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Recipient.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Recipient.java
deleted file mode 100644
index 56d2021..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/values/properties/Recipient.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.core.values.properties;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/**
- * Represents the value of the union property: http://schema.org/recipient, currently it only can
- * contain {@link Person}.
- */
-public class Recipient {
- private final Value mValue;
-
- public Recipient(@NonNull Person person) {
- mValue = new AutoValue_Recipient_Value(Optional.of(person));
- }
-
- @NonNull
- public Optional<Person> asPerson() {
- return mValue.person();
- }
-
- @Override
- public int hashCode() {
- return mValue.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (object instanceof Recipient) {
- Recipient that = (Recipient) object;
- return this.mValue.equals(that.mValue);
- }
- return false;
- }
-
- /** Represents the value in the this wrapper class. */
- @AutoValue
- abstract static class Value {
- abstract Optional<Person> person();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt
index b412f34..8e2af97 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/AlarmProvider.kt
@@ -16,8 +16,8 @@
package androidx.appactions.interaction.capabilities.core.entity
+import androidx.appactions.builtintypes.experimental.types.Alarm
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
/** Internal testing object for entity provider */
class AlarmProvider internal constructor(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt
index b7a58e7..72eeb27 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/entity/EntityProviderTest.kt
@@ -16,7 +16,7 @@
package androidx.appactions.interaction.capabilities.core.entity
-import androidx.appactions.interaction.capabilities.core.values.Alarm
+import androidx.appactions.builtintypes.experimental.types.Alarm
import androidx.appactions.interaction.proto.Entity
import androidx.appactions.interaction.proto.GroundingRequest
import androidx.appactions.interaction.proto.GroundingResponse
@@ -86,7 +86,7 @@
private fun createExternalCandidate(id: String, name: String): EntityLookupCandidate<Alarm> {
val candidateBuilder: EntityLookupCandidate.Builder<Alarm> =
EntityLookupCandidate.Builder()
- candidateBuilder.setCandidate(Alarm.newBuilder().setName(name).setId(id).build())
+ candidateBuilder.setCandidate(Alarm.Builder().setName(name).setIdentifier(id).build())
return candidateBuilder.build()
}
@@ -148,7 +148,7 @@
fun success() = runBlocking<Unit> {
val candidateBuilder: EntityLookupCandidate.Builder<Alarm> =
EntityLookupCandidate.Builder()
- candidateBuilder.setCandidate(Alarm.newBuilder().setName("testing-alarm").build())
+ candidateBuilder.setCandidate(Alarm.Builder().setName("testing-alarm").build())
val entityProvider = AlarmProvider(
"id",
createExternalResponse(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
index e94ab42..6b386e5 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
@@ -85,7 +85,7 @@
ArgumentUtils.buildArgs(
mapOf(
"optionalString" to
- ParamValue.newBuilder().setIdentifier("string argument value").build()
+ ParamValue.newBuilder().setStringValue("string argument value").build()
)
),
callbackInternal
@@ -138,7 +138,7 @@
ArgumentUtils.buildArgs(
mapOf(
"optionalString" to
- ParamValue.newBuilder().setIdentifier("string argument value").build()
+ ParamValue.newBuilder().setStringValue("string argument value").build()
)
),
callbackInternal
@@ -218,7 +218,7 @@
ArgumentUtils.buildArgs(
mapOf(
"optionalString" to
- ParamValue.newBuilder().setIdentifier("string value 1").build()
+ ParamValue.newBuilder().setStringValue("string value 1").build()
)
),
callbackInternal1
@@ -227,7 +227,7 @@
ArgumentUtils.buildArgs(
mapOf(
"optionalString" to
- ParamValue.newBuilder().setIdentifier("string value 2").build()
+ ParamValue.newBuilder().setStringValue("string value 2").build()
)
),
callbackInternal2
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java
index dd78f17..074820d 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConvertersTest.java
@@ -31,19 +31,20 @@
import static org.junit.Assert.assertThrows;
+import androidx.appactions.builtintypes.experimental.properties.Attendee;
+import androidx.appactions.builtintypes.experimental.properties.Participant;
+import androidx.appactions.builtintypes.experimental.properties.Recipient;
+import androidx.appactions.builtintypes.experimental.types.CalendarEvent;
+import androidx.appactions.builtintypes.experimental.types.Call;
+import androidx.appactions.builtintypes.experimental.types.ItemList;
+import androidx.appactions.builtintypes.experimental.types.ListItem;
+import androidx.appactions.builtintypes.experimental.types.Message;
+import androidx.appactions.builtintypes.experimental.types.Person;
+import androidx.appactions.builtintypes.experimental.types.SafetyCheck;
+import androidx.appactions.builtintypes.experimental.types.Timer;
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.values.CalendarEvent;
-import androidx.appactions.interaction.capabilities.core.values.Call;
import androidx.appactions.interaction.capabilities.core.values.EntityValue;
-import androidx.appactions.interaction.capabilities.core.values.ItemList;
-import androidx.appactions.interaction.capabilities.core.values.ListItem;
-import androidx.appactions.interaction.capabilities.core.values.Message;
-import androidx.appactions.interaction.capabilities.core.values.Person;
-import androidx.appactions.interaction.capabilities.core.values.SafetyCheck;
import androidx.appactions.interaction.capabilities.core.values.SearchAction;
-import androidx.appactions.interaction.capabilities.core.values.Timer;
-import androidx.appactions.interaction.capabilities.core.values.properties.Participant;
-import androidx.appactions.interaction.capabilities.core.values.properties.Recipient;
import androidx.appactions.interaction.proto.Entity;
import androidx.appactions.interaction.proto.ParamValue;
import androidx.appactions.interaction.protobuf.ListValue;
@@ -71,44 +72,44 @@
}
private static final Person PERSON_JAVA_THING =
- Person.newBuilder()
+ Person.Builder()
.setName("name")
.setEmail("email")
.setTelephone("telephone")
- .setId("id")
+ .setIdentifier("id")
.build();
- private static final Person PERSON_JAVA_THING_2 = Person.newBuilder().setId("id2").build();
+ private static final Person PERSON_JAVA_THING_2 = Person.Builder().setIdentifier("id2").build();
private static final CalendarEvent CALENDAR_EVENT_JAVA_THING =
- CalendarEvent.newBuilder()
+ CalendarEvent.Builder()
.setStartDate(ZonedDateTime.of(2022, 1, 1, 8, 0, 0, 0, ZoneOffset.UTC))
.setEndDate(ZonedDateTime.of(2023, 1, 1, 8, 0, 0, 0, ZoneOffset.UTC))
- .addAttendee(PERSON_JAVA_THING)
- .addAttendee(PERSON_JAVA_THING_2)
+ .addAttendee(new Attendee(PERSON_JAVA_THING))
+ .addAttendee(new Attendee(PERSON_JAVA_THING_2))
.build();
private static final Call CALL_JAVA_THING =
- Call.newBuilder()
- .setId("id")
- .setCallFormat(Call.CallFormat.AUDIO)
+ Call.Builder()
+ .setIdentifier("id")
.addParticipant(PERSON_JAVA_THING)
.build();
private static final Message MESSAGE_JAVA_THING =
- Message.newBuilder()
- .setId("id")
+ Message.Builder()
+ .setIdentifier("id")
.addRecipient(PERSON_JAVA_THING)
- .setMessageText("hello")
+ .setText("hello")
.build();
private static final SafetyCheck SAFETY_CHECK_JAVA_THING =
- SafetyCheck.newBuilder()
- .setId("id")
+ SafetyCheck.Builder()
+ .setIdentifier("id")
.setDuration(Duration.ofMinutes(5))
- .setCheckinTime(ZonedDateTime.of(2023, 01, 10, 10, 0, 0, 0, ZoneOffset.UTC))
+ .setCheckInTime(ZonedDateTime.of(2023, 01, 10, 10, 0, 0, 0, ZoneOffset.UTC))
.build();
private static final Struct PERSON_STRUCT =
Struct.newBuilder()
.putFields("@type", Value.newBuilder().setStringValue("Person").build())
.putFields("identifier", Value.newBuilder().setStringValue("id").build())
- .putFields("name", Value.newBuilder().setStringValue("name").build())
+ .putFields("name",
+ Value.newBuilder().setStringValue("name").build())
.putFields("email", Value.newBuilder().setStringValue("email").build())
.putFields("telephone", Value.newBuilder().setStringValue("telephone").build())
.build();
@@ -150,7 +151,6 @@
Struct.newBuilder()
.putFields("@type", Value.newBuilder().setStringValue("Call").build())
.putFields("identifier", Value.newBuilder().setStringValue("id").build())
- .putFields("callFormat", Value.newBuilder().setStringValue("Audio").build())
.putFields(
"participant",
Value.newBuilder()
@@ -183,7 +183,7 @@
.putFields("identifier", Value.newBuilder().setStringValue("id").build())
.putFields("duration", Value.newBuilder().setStringValue("PT5M").build())
.putFields(
- "checkinTime",
+ "checkInTime",
Value.newBuilder().setStringValue("2023-01-10T10:00Z").build())
.build();
@@ -201,8 +201,8 @@
.build());
assertThat(
- SlotTypeConverter.ofSingular(TypeConverters.ENTITY_PARAM_VALUE_CONVERTER)
- .convert(input))
+ SlotTypeConverter.ofSingular(TypeConverters.ENTITY_PARAM_VALUE_CONVERTER)
+ .convert(input))
.isEqualTo(
EntityValue.newBuilder().setId("entity-id").setValue("string-val").build());
}
@@ -226,27 +226,12 @@
ParamValue.newBuilder().setStringValue("hello world").build());
assertThat(
- SlotTypeConverter.ofSingular(TypeConverters.STRING_PARAM_VALUE_CONVERTER)
- .convert(input))
+ SlotTypeConverter.ofSingular(TypeConverters.STRING_PARAM_VALUE_CONVERTER)
+ .convert(input))
.isEqualTo("hello world");
}
@Test
- public void toStringValue_withIdentifier() throws Exception {
- List<ParamValue> input =
- Collections.singletonList(
- ParamValue.newBuilder()
- .setIdentifier("id1")
- .setStringValue("hello world")
- .build());
-
- assertThat(
- SlotTypeConverter.ofSingular(TypeConverters.STRING_PARAM_VALUE_CONVERTER)
- .convert(input))
- .isEqualTo("id1");
- }
-
- @Test
public void toStringValue_fromSingleParam() throws Exception {
ParamValue input = ParamValue.newBuilder().setStringValue("hello world").build();
@@ -256,7 +241,7 @@
@Test
public void listItem_conversions_matchesExpected() throws Exception {
- ListItem listItem = ListItem.create("itemId", "Test Item");
+ ListItem listItem = ListItem.Builder().setIdentifier("itemId").setName("Test Item").build();
Struct listItemStruct =
Struct.newBuilder()
.putFields("@type", Value.newBuilder().setStringValue("ListItem").build())
@@ -270,20 +255,21 @@
assertThat(EntityConverter.Companion.of(LIST_ITEM_TYPE_SPEC).convert(listItem))
.isEqualTo(listItemProto);
assertThat(
- ParamValueConverter.Companion.of(LIST_ITEM_TYPE_SPEC)
- .fromParamValue(toParamValue(listItemStruct, "itemId")))
+ ParamValueConverter.Companion.of(LIST_ITEM_TYPE_SPEC)
+ .fromParamValue(toParamValue(listItemStruct, "itemId")))
.isEqualTo(listItem);
}
@Test
public void itemList_conversions_matchesExpected() throws Exception {
ItemList itemList =
- ItemList.newBuilder()
- .setId("testList")
+ ItemList.Builder()
+ .setIdentifier("testList")
.setName("Test List")
- .addListItem(
- ListItem.create("item1", "apple"),
- ListItem.create("item2", "banana"))
+ .addItemListElement(
+ ListItem.Builder().setIdentifier("item1").setName("apple").build())
+ .addItemListElement(
+ ListItem.Builder().setIdentifier("item2").setName("banana").build())
.build();
Struct itemListStruct =
Struct.newBuilder()
@@ -361,10 +347,8 @@
assertThat(EntityConverter.Companion.of(ITEM_LIST_TYPE_SPEC).convert(itemList))
.isEqualTo(itemListProto);
- assertThat(
- ParamValueConverter.Companion.of(ITEM_LIST_TYPE_SPEC)
- .fromParamValue(toParamValue(itemListStruct, "testList")))
- .isEqualTo(itemList);
+ assertThat(ParamValueConverter.Companion.of(ITEM_LIST_TYPE_SPEC)
+ .fromParamValue(toParamValue(itemListStruct, "testList"))).isEqualTo(itemList);
}
@Test
@@ -373,7 +357,7 @@
ParamValueConverter.Companion.of(PARTICIPANT_TYPE_SPEC);
ParamValue paramValue =
ParamValue.newBuilder()
- .setIdentifier(PERSON_JAVA_THING.getId().orElse("id"))
+ .setIdentifier(PERSON_JAVA_THING.getIdentifier())
.setStructValue(PERSON_STRUCT)
.build();
Participant participant = new Participant(PERSON_JAVA_THING);
@@ -396,7 +380,8 @@
ParamValueConverter.Companion.of(RECIPIENT_TYPE_SPEC);
ParamValue paramValue =
ParamValue.newBuilder()
- .setIdentifier(PERSON_JAVA_THING.getId().orElse("id"))
+ .setIdentifier(PERSON_JAVA_THING.getIdentifier() == null ? "id" :
+ PERSON_JAVA_THING.getIdentifier())
.setStructValue(PERSON_STRUCT)
.build();
Recipient recipient = new Recipient(PERSON_JAVA_THING);
@@ -486,7 +471,7 @@
.convert(input));
assertThat(thrown)
.hasMessageThat()
- .isEqualTo("Cannot parse boolean because bool_value is missing from ParamValue.");
+ .matches("cannot convert .+ into Value.");
}
@Test
@@ -501,7 +486,7 @@
.convert(input));
assertThat(thrown)
.hasMessageThat()
- .isEqualTo("Cannot parse integer because number_value is missing from ParamValue.");
+ .matches("cannot convert .+ into Value.");
}
@Test
@@ -511,9 +496,9 @@
ParamValue.newBuilder().setStringValue("2018-06-17").build());
assertThat(
- SlotTypeConverter.ofSingular(
- TypeConverters.LOCAL_DATE_PARAM_VALUE_CONVERTER)
- .convert(input))
+ SlotTypeConverter.ofSingular(
+ TypeConverters.LOCAL_DATE_PARAM_VALUE_CONVERTER)
+ .convert(input))
.isEqualTo(LocalDate.of(2018, 6, 17));
}
@@ -558,9 +543,9 @@
ParamValue.newBuilder().setStringValue("15:10:05").build());
assertThat(
- SlotTypeConverter.ofSingular(
- TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER)
- .convert(input))
+ SlotTypeConverter.ofSingular(
+ TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER)
+ .convert(input))
.isEqualTo(LocalTime.of(15, 10, 5));
}
@@ -604,8 +589,8 @@
ParamValue.newBuilder().setStringValue("America/New_York").build());
assertThat(
- SlotTypeConverter.ofSingular(TypeConverters.ZONE_ID_PARAM_VALUE_CONVERTER)
- .convert(input))
+ SlotTypeConverter.ofSingular(TypeConverters.ZONE_ID_PARAM_VALUE_CONVERTER)
+ .convert(input))
.isEqualTo(ZoneId.of("America/New_York"));
}
@@ -648,9 +633,9 @@
ParamValue.newBuilder().setStringValue("2018-06-17T15:10:05Z").build());
assertThat(
- SlotTypeConverter.ofSingular(
- TypeConverters.ZONED_DATETIME_PARAM_VALUE_CONVERTER)
- .convert(input))
+ SlotTypeConverter.ofSingular(
+ TypeConverters.ZONED_DATETIME_PARAM_VALUE_CONVERTER)
+ .convert(input))
.isEqualTo(ZonedDateTime.of(2018, 6, 17, 15, 10, 5, 0, ZoneOffset.UTC));
}
@@ -751,8 +736,8 @@
@Test
public void searchActionConverter_withNestedObject() throws Exception {
ItemList itemList =
- ItemList.newBuilder()
- .addListItem(ListItem.newBuilder().setName("sugar").build())
+ ItemList.Builder()
+ .addItemListElement(ListItem.Builder().setName("sugar").build())
.build();
Struct nestedObject = TypeConverters.ITEM_LIST_TYPE_SPEC.toValue(itemList).getStructValue();
ParamValue input =
@@ -790,24 +775,24 @@
public void toTimer_success() throws Exception {
ParamValueConverter<Timer> paramValueConverter =
ParamValueConverter.Companion.of(TIMER_TYPE_SPEC);
- Timer timer = Timer.newBuilder().setId("abc").build();
+ Timer timer = Timer.Builder().setIdentifier("abc").build();
assertThat(
- paramValueConverter.fromParamValue(
- ParamValue.newBuilder()
- .setStructValue(
- Struct.newBuilder()
- .putFields(
- "@type",
- Value.newBuilder()
- .setStringValue("Timer")
- .build())
- .putFields(
- "identifier",
- Value.newBuilder()
- .setStringValue("abc")
- .build()))
- .build()))
+ paramValueConverter.fromParamValue(
+ ParamValue.newBuilder()
+ .setStructValue(
+ Struct.newBuilder()
+ .putFields(
+ "@type",
+ Value.newBuilder()
+ .setStringValue("Timer")
+ .build())
+ .putFields(
+ "identifier",
+ Value.newBuilder()
+ .setStringValue("abc")
+ .build()))
+ .build()))
.isEqualTo(timer);
}
@@ -836,8 +821,8 @@
@Test
public void toParamValues_safetyCheck_success() {
assertThat(
- ParamValueConverter.Companion.of(SAFETY_CHECK_TYPE_SPEC)
- .toParamValue(SAFETY_CHECK_JAVA_THING))
+ ParamValueConverter.Companion.of(SAFETY_CHECK_TYPE_SPEC)
+ .toParamValue(SAFETY_CHECK_JAVA_THING))
.isEqualTo(
ParamValue.newBuilder()
.setStructValue(SAFETY_CHECK_STRUCT)
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
index cad1967..74057e2 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/UnionTypeSpecTest.kt
@@ -16,8 +16,8 @@
package androidx.appactions.interaction.capabilities.core.impl.converters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
-import androidx.appactions.interaction.capabilities.core.values.Timer
+import androidx.appactions.builtintypes.experimental.types.Alarm
+import androidx.appactions.builtintypes.experimental.types.Timer
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -48,9 +48,9 @@
class UnionTypeSpecTest {
@Test
fun unionType_identifier() {
- val alarmUnion = AlarmOrTimer(Alarm.newBuilder().setId("alarmId").build())
- val timerUnion = AlarmOrTimer(Timer.newBuilder().setId("timerId").build())
- val timerUnionWithoutId = AlarmOrTimer(Timer.newBuilder().build())
+ val alarmUnion = AlarmOrTimer(Alarm.Builder().setIdentifier("alarmId").build())
+ val timerUnion = AlarmOrTimer(Timer.Builder().setIdentifier("timerId").build())
+ val timerUnionWithoutId = AlarmOrTimer(Timer.Builder().build())
assertThat(ALARM_OR_TIMER_TYPE_SPEC.getIdentifier(alarmUnion)).isEqualTo("alarmId")
assertThat(ALARM_OR_TIMER_TYPE_SPEC.getIdentifier(timerUnion)).isEqualTo("timerId")
assertThat(ALARM_OR_TIMER_TYPE_SPEC.getIdentifier(timerUnionWithoutId)).isNull()
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
index 932f146..4ab5a88 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
@@ -16,6 +16,7 @@
package androidx.appactions.interaction.capabilities.core.impl.task
import android.util.SizeF
+import androidx.appactions.builtintypes.experimental.types.ListItem
import androidx.appactions.interaction.capabilities.core.AppEntityListener
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.EntitySearchResult
@@ -46,7 +47,6 @@
import androidx.appactions.interaction.capabilities.core.testing.spec.TestEnum
import androidx.appactions.interaction.capabilities.core.testing.spec.Properties
import androidx.appactions.interaction.capabilities.core.values.EntityValue
-import androidx.appactions.interaction.capabilities.core.values.ListItem
import androidx.appactions.interaction.capabilities.core.values.SearchAction
import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildRequestArgs
import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildSearchActionParamValue
@@ -146,6 +146,7 @@
override fun onCreate(sessionContext: SessionContext) {
onCreateInvocationCount.incrementAndGet()
}
+
override fun onExecuteAsync(arguments: Arguments) =
Futures.immediateFuture(
ExecutionResult.Builder<Output>().build(),
@@ -702,8 +703,9 @@
.setListItem(Property.Builder<ListItem>().setRequired(true).build())
.setAnyString(Property.Builder<StringValue>().setRequired(true).build())
.build()
- val item1: ListItem = ListItem.newBuilder().setName("red apple").setId("item1").build()
- val item2: ListItem = ListItem.newBuilder().setName("green apple").setId("item2").build()
+ val item1: ListItem = ListItem.Builder().setName("red apple").setIdentifier("item1").build()
+ val item2: ListItem =
+ ListItem.Builder().setName("green apple").setIdentifier("item2").build()
val onReceivedDeferred = CompletableDeferred<ListItem>()
val onExecuteListItemDeferred = CompletableDeferred<ListItem>()
val onExecuteStringDeferred = CompletableDeferred<String>()
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
index d8d9872..049344e 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
@@ -29,8 +29,6 @@
import androidx.appactions.interaction.proto.DisambiguationData
import androidx.appactions.interaction.proto.Entity
import androidx.appactions.interaction.proto.ParamValue
-import androidx.appactions.interaction.protobuf.Struct
-import androidx.appactions.interaction.protobuf.Value
import com.google.common.truth.Truth.assertThat
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.CompletableDeferred
@@ -132,7 +130,7 @@
)
val taskParamMap: MutableMap<String, TaskParamBinding<*>> = HashMap()
taskParamMap["singularValue"] = binding
- val args = listOf(ParamValue.newBuilder().setIdentifier("testValue").build())
+ val args = listOf(ParamValue.newBuilder().setStringValue("testValue").build())
val (isSuccessful, processedValues) =
TaskSlotProcessor.processSlot(
"singularValue",
@@ -163,7 +161,7 @@
)
val taskParamMap: MutableMap<String, TaskParamBinding<*>> = HashMap()
taskParamMap["singularValue"] = binding
- val args = listOf(ParamValue.newBuilder().setIdentifier("testValue").build())
+ val args = listOf(ParamValue.newBuilder().setStringValue("testValue").build())
val (isSuccessful, processedValues) =
TaskSlotProcessor.processSlot(
"singularValue",
@@ -199,8 +197,8 @@
taskParamMap["repeatedValue"] = binding
val args =
listOf(
- ParamValue.newBuilder().setIdentifier("testValue1").build(),
- ParamValue.newBuilder().setIdentifier("testValue2").build(),
+ ParamValue.newBuilder().setStringValue("testValue1").build(),
+ ParamValue.newBuilder().setStringValue("testValue2").build(),
)
val (isSuccessful, processedValues) =
TaskSlotProcessor.processSlot(
@@ -247,8 +245,8 @@
taskParamMap["repeatedValue"] = binding
val args =
listOf(
- ParamValue.newBuilder().setIdentifier("testValue1").build(),
- ParamValue.newBuilder().setIdentifier("testValue2").build(),
+ ParamValue.newBuilder().setStringValue("testValue1").build(),
+ ParamValue.newBuilder().setStringValue("testValue2").build(),
)
val (isSuccessful, processedValues) =
TaskSlotProcessor.processSlot(
@@ -304,13 +302,7 @@
.setValue(
ParamValue.newBuilder()
.setIdentifier("id")
- .setStructValue(
- Struct.newBuilder()
- .putFields(
- "id",
- Value.newBuilder().setStringValue("1234").build(),
- ),
- ),
+ .setStringValue("1234")
)
.build()
val values =
@@ -328,7 +320,7 @@
val (isSuccessful, processedValues) =
TaskSlotProcessor.processSlot("assistantDrivenSlot", values, taskParamMap)
assertThat(isSuccessful).isFalse()
- assertThat(onReceivedDeferred.awaitSync()).isEqualTo("id")
+ assertThat(onReceivedDeferred.awaitSync()).isEqualTo("1234")
assertThat(renderDeferred.awaitSync()).isEqualTo(listOf("entity-1", "entity-2"))
assertThat(processedValues)
.containsExactly(
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
index 1b8a88e..a2317c7 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
@@ -19,6 +19,7 @@
import static androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.LIST_ITEM_TYPE_SPEC;
import androidx.annotation.NonNull;
+import androidx.appactions.builtintypes.experimental.types.ListItem;
import androidx.appactions.interaction.capabilities.core.AppEntityListener;
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession;
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
@@ -29,7 +30,6 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder;
import androidx.appactions.interaction.capabilities.core.properties.Property;
import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-import androidx.appactions.interaction.capabilities.core.values.ListItem;
import com.google.auto.value.AutoValue;
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
index f4a5294..14c0fed 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
@@ -16,14 +16,14 @@
package androidx.appactions.interaction.capabilities.productivity
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
index ec8fea6..d05acf9 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
@@ -16,14 +16,14 @@
package androidx.appactions.interaction.capabilities.productivity
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
index d8b2fb0..accb730 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
@@ -16,14 +16,14 @@
package androidx.appactions.interaction.capabilities.productivity
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
index 360b356..8a96645 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
@@ -16,6 +16,8 @@
package androidx.appactions.interaction.capabilities.productivity
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.ExecutionSessionFactory
@@ -27,8 +29,6 @@
import androidx.appactions.interaction.capabilities.core.properties.Property
import androidx.appactions.interaction.capabilities.core.impl.task.SessionBridge
import androidx.appactions.interaction.capabilities.core.impl.task.TaskHandler
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
index c018c60..fa589e7 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
@@ -16,14 +16,14 @@
package androidx.appactions.interaction.capabilities.productivity
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
index f642bb1..ff9ae5b 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
@@ -16,12 +16,12 @@
package androidx.appactions.interaction.capabilities.productivity
+import androidx.appactions.builtintypes.experimental.types.Timer
import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
import androidx.appactions.interaction.capabilities.core.values.SearchAction
-import androidx.appactions.interaction.capabilities.core.values.Timer
import java.util.Objects
class TimerValue
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
index 79e0bd3..a0829de 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
@@ -16,14 +16,14 @@
package androidx.appactions.interaction.capabilities.safety
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
import androidx.appactions.interaction.capabilities.safety.executionstatus.EmergencySharingInProgress
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
index 0bf2a33..cd5b319 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
@@ -16,6 +16,11 @@
package androidx.appactions.interaction.capabilities.safety
+import androidx.appactions.builtintypes.experimental.types.ActionNotInProgress
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
+import androidx.appactions.builtintypes.experimental.types.SafetyCheck
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
@@ -24,11 +29,6 @@
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.SAFETY_CHECK_TYPE_SPEC
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SafetyCheck
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.ActionNotInProgress
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
import androidx.appactions.interaction.capabilities.safety.executionstatus.EmergencySharingInProgress
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
index 1224831..afc9f18 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
@@ -16,15 +16,15 @@
package androidx.appactions.interaction.capabilities.safety
+import androidx.appactions.builtintypes.experimental.types.ActionNotInProgress
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.ActionNotInProgress
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
import androidx.appactions.interaction.proto.ParamValue
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
index 01d3ff9..3e5156b 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
@@ -16,15 +16,15 @@
package androidx.appactions.interaction.capabilities.safety
+import androidx.appactions.builtintypes.experimental.types.ActionNotInProgress
+import androidx.appactions.builtintypes.experimental.types.GenericErrorStatus
+import androidx.appactions.builtintypes.experimental.types.NoInternetConnection
+import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
-import androidx.appactions.interaction.capabilities.core.values.GenericErrorStatus
-import androidx.appactions.interaction.capabilities.core.values.SuccessStatus
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.ActionNotInProgress
-import androidx.appactions.interaction.capabilities.core.values.executionstatus.NoInternetConnection
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyAccountNotLoggedIn
import androidx.appactions.interaction.capabilities.safety.executionstatus.SafetyFeatureNotOnboarded
import androidx.appactions.interaction.proto.ParamValue
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.java b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.java
deleted file mode 100644
index 86c1e31..0000000
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.safety.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to emergency sharing being in progress. */
-@AutoValue
-public abstract class EmergencySharingInProgress extends Thing {
-
- /** Builder class for EmergencySharingInProgress status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<EmergencySharingInProgress> {
- }
-
- /** Create a new EmergencySharingInProgress instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_EmergencySharingInProgress.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static EmergencySharingInProgress getDefaultInstance() {
- return new AutoValue_EmergencySharingInProgress.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "EmergencySharingInProgress";
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.kt
new file mode 100644
index 0000000..4fc874c
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/EmergencySharingInProgress.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.safety.executionstatus
+
+import androidx.appactions.builtintypes.experimental.properties.Name
+import androidx.appactions.builtintypes.experimental.types.Thing
+
+interface EmergencySharingInProgress : Thing {
+ override fun toBuilder(): Builder<*>
+
+ companion object {
+ @JvmStatic
+ fun Builder(): Builder<*> = EmergencySharingInProgressBuilderImpl()
+ }
+
+ interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
+ override fun build(): EmergencySharingInProgress
+ }
+}
+
+private class EmergencySharingInProgressBuilderImpl :
+ EmergencySharingInProgress.Builder<EmergencySharingInProgressBuilderImpl> {
+
+ private var identifier: String? = null
+ private var name: Name? = null
+
+ override fun build() = EmergencySharingInProgressImpl(identifier, name)
+
+ override fun setIdentifier(text: String?): EmergencySharingInProgressBuilderImpl =
+ apply { identifier = text }
+
+ override fun setName(text: String): EmergencySharingInProgressBuilderImpl =
+ apply { name = Name(text) }
+
+ override fun setName(name: Name?): EmergencySharingInProgressBuilderImpl =
+ apply { this.name = name }
+
+ override fun clearName(): EmergencySharingInProgressBuilderImpl = apply { name = null }
+}
+
+private class EmergencySharingInProgressImpl(
+ override val identifier: String?,
+ override val name: Name?
+) :
+ EmergencySharingInProgress {
+ override fun toBuilder(): EmergencySharingInProgress.Builder<*> =
+ EmergencySharingInProgressBuilderImpl().setIdentifier(identifier).setName(name)
+
+ override fun toString(): String = "EmergencySharingInProgress"
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.java b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.java
deleted file mode 100644
index f4b9b4f..0000000
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.safety.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to logged out account. */
-@AutoValue
-public abstract class SafetyAccountNotLoggedIn extends Thing {
-
- /** Builder class for SafetyAccountNotLoggedIn status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<SafetyAccountNotLoggedIn> {
- }
-
- /** Create a new SafetyAccountNotLoggedIn instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_SafetyAccountNotLoggedIn.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static SafetyAccountNotLoggedIn getDefaultInstance() {
- return new AutoValue_SafetyAccountNotLoggedIn.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "SafetyAccountNotLoggedIn";
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.kt
new file mode 100644
index 0000000..fed52ff
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyAccountNotLoggedIn.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.safety.executionstatus
+
+import androidx.appactions.builtintypes.experimental.properties.Name
+import androidx.appactions.builtintypes.experimental.types.Thing
+
+interface SafetyAccountNotLoggedIn : Thing {
+ override fun toBuilder(): Builder<*>
+
+ companion object {
+ @JvmStatic
+ fun Builder(): Builder<*> = SafetyAccountNotLoggedInBuilderImpl()
+ }
+
+ interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
+ override fun build(): SafetyAccountNotLoggedIn
+ }
+}
+
+private class SafetyAccountNotLoggedInBuilderImpl :
+ SafetyAccountNotLoggedIn.Builder<SafetyAccountNotLoggedInBuilderImpl> {
+
+ private var identifier: String? = null
+ private var name: Name? = null
+
+ override fun build() = SafetyAccountNotLoggedInImpl(identifier, name)
+
+ override fun setIdentifier(text: String?): SafetyAccountNotLoggedInBuilderImpl =
+ apply { identifier = text }
+
+ override fun setName(text: String): SafetyAccountNotLoggedInBuilderImpl =
+ apply { name = Name(text) }
+
+ override fun setName(name: Name?): SafetyAccountNotLoggedInBuilderImpl =
+ apply { this.name = name }
+
+ override fun clearName(): SafetyAccountNotLoggedInBuilderImpl = apply { name = null }
+}
+
+private class SafetyAccountNotLoggedInImpl(
+ override val identifier: String?,
+ override val name: Name?
+) :
+ SafetyAccountNotLoggedIn {
+ override fun toBuilder(): SafetyAccountNotLoggedIn.Builder<*> =
+ SafetyAccountNotLoggedInBuilderImpl().setIdentifier(identifier).setName(name)
+
+ override fun toString(): String = "SafetyAccountNotLoggedIn"
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.java b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.java
deleted file mode 100644
index cfed520..0000000
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appactions.interaction.capabilities.safety.executionstatus;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.values.Thing;
-
-import com.google.auto.value.AutoValue;
-
-/** Error status for execution failure due to user not being onboard. */
-@AutoValue
-public abstract class SafetyFeatureNotOnboarded extends Thing {
-
- /** Builder class for SafetyFeatureNotOnboarded status. */
- @AutoValue.Builder
- public abstract static class Builder extends Thing.Builder<Builder>
- implements BuilderOf<SafetyFeatureNotOnboarded> {
- }
-
- /** Create a new SafetyFeatureNotOnboarded instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_SafetyFeatureNotOnboarded.Builder();
- }
-
- /** Create a new default instance. */
- @NonNull
- public static SafetyFeatureNotOnboarded getDefaultInstance() {
- return new AutoValue_SafetyFeatureNotOnboarded.Builder().build();
- }
-
- @Override
- public final String toString() {
- return "SafetyFeatureNotOnboarded";
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.kt
new file mode 100644
index 0000000..46d84ab
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/executionstatus/SafetyFeatureNotOnboarded.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appactions.interaction.capabilities.safety.executionstatus
+
+import androidx.appactions.builtintypes.experimental.properties.Name
+import androidx.appactions.builtintypes.experimental.types.Thing
+
+interface SafetyFeatureNotOnboarded : Thing {
+ override fun toBuilder(): Builder<*>
+
+ companion object {
+ @JvmStatic
+ fun Builder(): Builder<*> = SafetyFeatureNotOnboardedBuilderImpl()
+ }
+
+ interface Builder<Self : Builder<Self>> : Thing.Builder<Self> {
+ override fun build(): SafetyFeatureNotOnboarded
+ }
+}
+
+private class SafetyFeatureNotOnboardedBuilderImpl :
+ SafetyFeatureNotOnboarded.Builder<SafetyFeatureNotOnboardedBuilderImpl> {
+
+ private var identifier: String? = null
+ private var name: Name? = null
+
+ override fun build() = SafetyFeatureNotOnboardedImpl(identifier, name)
+
+ override fun setIdentifier(text: String?): SafetyFeatureNotOnboardedBuilderImpl =
+ apply { identifier = text }
+
+ override fun setName(text: String): SafetyFeatureNotOnboardedBuilderImpl =
+ apply { name = Name(text) }
+
+ override fun setName(name: Name?): SafetyFeatureNotOnboardedBuilderImpl =
+ apply { this.name = name }
+
+ override fun clearName(): SafetyFeatureNotOnboardedBuilderImpl = apply { name = null }
+}
+
+private class SafetyFeatureNotOnboardedImpl(
+ override val identifier: String?,
+ override val name: Name?
+) :
+ SafetyFeatureNotOnboarded {
+ override fun toBuilder(): SafetyFeatureNotOnboarded.Builder<*> =
+ SafetyFeatureNotOnboardedBuilderImpl().setIdentifier(identifier).setName(name)
+
+ override fun toString(): String = "SafetyFeatureNotOnboarded"
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt
index 6f339d4..b571b2f 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceEntityProviderTest.kt
@@ -16,9 +16,9 @@
package androidx.appactions.interaction.service
+import androidx.appactions.builtintypes.experimental.types.Alarm
import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildSearchActionParamValue
import androidx.appactions.interaction.capabilities.testing.internal.TestingUtils.awaitSync
import androidx.appactions.interaction.proto.GroundingRequest
@@ -66,7 +66,7 @@
@Test
fun alarmProvider_incorrectProviderId(): Unit = runBlocking {
- val morningAlarm = Alarm.newBuilder().setId("alarm1").setName("Morning Alarm").build()
+ val morningAlarm = Alarm.Builder().setIdentifier("alarm1").setName("Morning Alarm").build()
val alarmProvider = FakeAlarmEntityProvider(
"alarmProvider",
listOf(morningAlarm)
@@ -110,7 +110,7 @@
@Test
fun alarmProvider_success(): Unit = runBlocking {
- val morningAlarm = Alarm.newBuilder().setId("alarm1").setName("Morning Alarm").build()
+ val morningAlarm = Alarm.Builder().setIdentifier("alarm1").setName("Morning Alarm").build()
val alarmProvider = FakeAlarmEntityProvider(
"alarmProvider",
listOf(morningAlarm)
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
index 84f10a2..e9e60c5 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
@@ -270,7 +270,7 @@
session.execute(
buildArgs(
mapOf(
- "fieldOne" to ParamValue.newBuilder().setIdentifier("hello").build(),
+ "fieldOne" to ParamValue.newBuilder().setStringValue("hello").build(),
),
),
callback,
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
index c2b23b1..fd99a27 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
@@ -16,12 +16,12 @@
package androidx.appactions.interaction.service.testing.internal
+import androidx.appactions.builtintypes.experimental.types.Alarm
import androidx.appactions.interaction.capabilities.core.entity.EntityProvider
import androidx.appactions.interaction.capabilities.core.entity.EntityLookupRequest
import androidx.appactions.interaction.capabilities.core.entity.EntityLookupResponse
import androidx.appactions.interaction.capabilities.core.entity.EntityLookupCandidate
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.values.Alarm
class FakeAlarmEntityProvider(
override val id: String,
diff --git a/benchmark/benchmark-junit4/api/api_lint.ignore b/benchmark/benchmark-junit4/api/api_lint.ignore
index fa24057..e28c732 100644
--- a/benchmark/benchmark-junit4/api/api_lint.ignore
+++ b/benchmark/benchmark-junit4/api/api_lint.ignore
@@ -1,4 +1,10 @@
// Baseline format: 1.0
+GetterSetterNames: field PerfettoTraceRule.enableAppTagTracing:
+ Invalid name for boolean property `enableAppTagTracing`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PerfettoTraceRule.enableUserspaceTracing:
+ Invalid name for boolean property `enableUserspaceTracing`. Should start with one of `has`, `can`, `should`, `is`.
+
+
InvalidNullabilityOverride: androidx.benchmark.junit4.BenchmarkRule#apply(org.junit.runners.model.Statement, org.junit.runner.Description) parameter #0:
Invalid nullability on parameter `base` in method `apply`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
InvalidNullabilityOverride: androidx.benchmark.junit4.BenchmarkRule#apply(org.junit.runners.model.Statement, org.junit.runner.Description) parameter #1:
diff --git a/benchmark/benchmark-junit4/api/current.txt b/benchmark/benchmark-junit4/api/current.txt
index 873f105..819dd90 100644
--- a/benchmark/benchmark-junit4/api/current.txt
+++ b/benchmark/benchmark-junit4/api/current.txt
@@ -12,7 +12,7 @@
}
public final class BenchmarkRule.Scope {
- method public inline <T> T! runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
}
public final class BenchmarkRuleKt {
diff --git a/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt b/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt
index b376c11..f68f2a0 100644
--- a/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-junit4/api/public_plus_experimental_current.txt
@@ -12,7 +12,7 @@
}
public final class BenchmarkRule.Scope {
- method public inline <T> T! runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
}
public final class BenchmarkRuleKt {
diff --git a/benchmark/benchmark-junit4/api/restricted_current.txt b/benchmark/benchmark-junit4/api/restricted_current.txt
index c2d8056..1003a639 100644
--- a/benchmark/benchmark-junit4/api/restricted_current.txt
+++ b/benchmark/benchmark-junit4/api/restricted_current.txt
@@ -13,7 +13,7 @@
public final class BenchmarkRule.Scope {
method @kotlin.PublishedApi internal androidx.benchmark.BenchmarkState getOuterState();
- method public inline <T> T! runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <T> T runWithTimingDisabled(kotlin.jvm.functions.Function0<? extends T> block);
}
public final class BenchmarkRuleKt {
diff --git a/benchmark/benchmark-macro/api/api_lint.ignore b/benchmark/benchmark-macro/api/api_lint.ignore
new file mode 100644
index 0000000..33968af
--- /dev/null
+++ b/benchmark/benchmark-macro/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field Metric.Measurement.requireSingleValue:
+ Invalid name for boolean property `requireSingleValue`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
index 86e2432..1597078 100644
--- a/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-macro/api/public_plus_experimental_current.txt
@@ -208,13 +208,13 @@
@androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi public final class PerfettoTraceProcessor {
ctor public PerfettoTraceProcessor();
- method public <T> T! loadTrace(androidx.benchmark.perfetto.PerfettoTrace trace, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor.Session,? extends T> block);
- method public static <T> T! runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+ method public <T> T loadTrace(androidx.benchmark.perfetto.PerfettoTrace trace, kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor.Session,? extends T> block);
+ method public static <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
field public static final androidx.benchmark.perfetto.PerfettoTraceProcessor.Companion Companion;
}
public static final class PerfettoTraceProcessor.Companion {
- method public <T> T! runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
+ method public <T> T runServer(kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTraceProcessor,? extends T> block);
}
public static final class PerfettoTraceProcessor.Session {
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt
index 6398e36..055ccfd 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/ProfileInstallBroadcastTest.kt
@@ -19,13 +19,10 @@
import android.os.Build
import androidx.benchmark.junit4.PerfettoTraceRule
import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
-import androidx.core.os.BuildCompat
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import kotlin.test.assertNull
-import org.junit.Assume
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -37,12 +34,6 @@
@get:Rule
val perfettoTraceRule = PerfettoTraceRule()
- @Before
- fun setUp() {
- // TODO: to re-enable for api 34 (b/276970167)
- Assume.assumeTrue(!BuildCompat.isAtLeastU())
- }
-
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
@Test
fun installProfile() {
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AddressType.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AddressType.kt
new file mode 100644
index 0000000..02f2550
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/AddressType.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth
+
+import android.bluetooth.BluetoothDevice
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+
+/**
+ * Represents a Bluetooth device address type.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+ AddressType.ADDRESS_TYPE_PUBLIC,
+ AddressType.ADDRESS_TYPE_RANDOM,
+ AddressType.ADDRESS_TYPE_UNKNOWN
+)
+public annotation class AddressType {
+ companion object {
+ /* Address type is public and registered with the IEEE. */
+ public const val ADDRESS_TYPE_PUBLIC: Int = BluetoothDevice.ADDRESS_TYPE_PUBLIC
+
+ /* Address type is random. */
+ public const val ADDRESS_TYPE_RANDOM: Int = BluetoothDevice.ADDRESS_TYPE_RANDOM
+
+ /* Address type is unknown. */
+ public const val ADDRESS_TYPE_UNKNOWN: Int = BluetoothDevice.ADDRESS_TYPE_UNKNOWN
+ }
+}
\ No newline at end of file
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanType.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanType.kt
new file mode 100644
index 0000000..e26a338
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanType.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth
+
+import android.bluetooth.le.ScanSettings
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+
+/**
+ * Bluetooth LE scan type that defines which scan results to send into the scan flow.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+ ScanType.ALL_MATCHES,
+ ScanType.FIRST_MATCH,
+ ScanType.MATCH_LOST
+)
+public annotation class ScanType {
+ companion object {
+ /* Send scan result for every Bluetooth advertisement that matches the filter criteria. */
+ public const val ALL_MATCHES: Int = ScanSettings.CALLBACK_TYPE_ALL_MATCHES
+
+ /**
+ * Send scan result for only the first advertisement packet received that matches the filter
+ * criteria.
+ */
+ public const val FIRST_MATCH: Int = ScanSettings.CALLBACK_TYPE_FIRST_MATCH
+
+ /**
+ * Send scan result when advertisements are no longer received from a device that has been
+ * previously reported by a first match scan type.
+ */
+ public const val MATCH_LOST: Int = ScanSettings.CALLBACK_TYPE_MATCH_LOST
+ }
+}
\ No newline at end of file
diff --git a/bluetooth/integration-tests/testapp/build.gradle b/bluetooth/integration-tests/testapp/build.gradle
index 18d2ce1..ba207e7 100644
--- a/bluetooth/integration-tests/testapp/build.gradle
+++ b/bluetooth/integration-tests/testapp/build.gradle
@@ -44,22 +44,20 @@
dependencies {
implementation(libs.kotlinStdlib)
-
implementation(project(":bluetooth:bluetooth"))
- implementation("androidx.core:core-ktx:1.9.0")
+ implementation("androidx.activity:activity-ktx:1.7.0")
implementation("androidx.appcompat:appcompat:1.6.1")
+ implementation(libs.constraintLayout)
+ implementation("androidx.core:core-ktx:1.10.0")
+ implementation("androidx.fragment:fragment-ktx:1.5.6")
+ implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
+ implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
+ implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
+ implementation("androidx.recyclerview:recyclerview:1.3.0")
implementation(libs.material)
- implementation("androidx.activity:activity-ktx:1.7.0")
- implementation("androidx.fragment:fragment-ktx:1.5.6")
-
- implementation(libs.constraintLayout)
-
- implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
- implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
-
- implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
- implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiseDataAdapter.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiseDataAdapter.kt
new file mode 100644
index 0000000..a48c218
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiseDataAdapter.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth.integration.testapp.ui.advertiser
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.TextView
+import androidx.bluetooth.integration.testapp.R
+import androidx.recyclerview.widget.RecyclerView
+
+class AdvertiseDataAdapter(var advertiseData: List<String>, private val onClick: (Int) -> Unit) :
+ RecyclerView.Adapter<AdvertiseDataAdapter.ViewHolder>() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_advertiser_data, parent, false)
+ return ViewHolder(view, onClick)
+ }
+
+ override fun getItemCount(): Int {
+ return advertiseData.size
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val advertiseData = advertiseData[position]
+ holder.bind(advertiseData)
+ }
+
+ inner class ViewHolder(itemView: View, private val onClick: (Int) -> Unit) :
+ RecyclerView.ViewHolder(itemView) {
+
+ private val textViewData: TextView = itemView.findViewById(R.id.text_view_data)
+ private val imageButtonClear: ImageButton = itemView.findViewById(R.id.image_button_clear)
+
+ init {
+ imageButtonClear.setOnClickListener {
+ imageButtonClear.isClickable = false
+ onClick(absoluteAdapterPosition)
+ }
+ }
+
+ fun bind(advertiseData: String) {
+ textViewData.text = advertiseData
+ imageButtonClear.isClickable = true
+ }
+ }
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
index 3f12108..73c1935 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
@@ -16,20 +16,61 @@
package androidx.bluetooth.integration.testapp.ui.advertiser
+import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.EditText
+
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.widget.PopupMenu
+import androidx.bluetooth.AdvertiseResult
+import androidx.bluetooth.BluetoothLe
+import androidx.bluetooth.integration.testapp.R
import androidx.bluetooth.integration.testapp.databinding.FragmentAdvertiserBinding
+import androidx.bluetooth.integration.testapp.ui.common.setViewEditText
+import androidx.bluetooth.integration.testapp.ui.common.toast
+import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+import java.util.UUID
class AdvertiserFragment : Fragment() {
- companion object {
+ private companion object {
private const val TAG = "AdvertiserFragment"
}
+ private lateinit var advertiserViewModel: AdvertiserViewModel
+
+ private lateinit var bluetoothLe: BluetoothLe
+
+ private var advertiseDataAdapter: AdvertiseDataAdapter? = null
+
+ private val advertiseScope = CoroutineScope(Dispatchers.Main + Job())
+ private var advertiseJob: Job? = null
+
+ private var isAdvertising: Boolean = false
+ set(value) {
+ field = value
+ if (value) {
+ _binding?.buttonAdvertise?.text = getString(R.string.stop_advertising)
+ } else {
+ _binding?.buttonAdvertise?.text = getString(R.string.start_advertising)
+ advertiseJob?.cancel()
+ advertiseJob = null
+ }
+ _binding?.viewOverlay?.isVisible = value
+ }
+
private var _binding: FragmentAdvertiserBinding? = null
// This property is only valid between onCreateView and onDestroyView.
@@ -40,17 +81,188 @@
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
- Log.d(
- TAG, "onCreateView() called with: inflater = $inflater, " +
- "container = $container, savedInstanceState = $savedInstanceState"
- )
+ advertiserViewModel = ViewModelProvider(this)[AdvertiserViewModel::class.java]
+
+ bluetoothLe = BluetoothLe(requireContext())
_binding = FragmentAdvertiserBinding.inflate(inflater, container, false)
+
+ initData()
+
+ binding.checkBoxIncludeDeviceName.setOnCheckedChangeListener { _, isChecked ->
+ advertiserViewModel.includeDeviceName = isChecked
+ }
+
+ binding.checkBoxConnectable.setOnCheckedChangeListener { _, isChecked ->
+ advertiserViewModel.connectable = isChecked
+ }
+
+ binding.checkBoxDiscoverable.setOnCheckedChangeListener { _, isChecked ->
+ advertiserViewModel.discoverable = isChecked
+ }
+
+ binding.buttonAddData.setOnClickListener {
+ with(PopupMenu(requireContext(), binding.buttonAddData)) {
+ menu.add(getString(R.string.service_uuid))
+ menu.add(getString(R.string.service_data))
+ menu.add(getString(R.string.manufacturer_data))
+
+ setOnMenuItemClickListener { menuItem ->
+ showDialogFor(menuItem.title.toString())
+ true
+ }
+ show()
+ }
+ }
+
+ advertiseDataAdapter = AdvertiseDataAdapter(
+ advertiserViewModel.advertiseData,
+ ::onClickRemoveAdvertiseData
+ )
+ binding.recyclerViewAdvertiseData.adapter = advertiseDataAdapter
+
+ binding.buttonAdvertise.setOnClickListener {
+ if (advertiseJob?.isActive == true) {
+ isAdvertising = false
+ } else {
+ startAdvertise()
+ }
+ }
+
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
+ isAdvertising = false
+ }
+
+ private fun initData() {
+ binding.checkBoxIncludeDeviceName.isChecked = advertiserViewModel.includeDeviceName
+ binding.checkBoxConnectable.isChecked = advertiserViewModel.connectable
+ binding.checkBoxDiscoverable.isChecked = advertiserViewModel.discoverable
+ }
+
+ private fun showDialogFor(title: String) {
+ when (title) {
+ getString(R.string.service_uuid) -> showDialogForServiceUuid()
+ getString(R.string.service_data) -> showDialogForServiceData()
+ getString(R.string.manufacturer_data) -> showDialogForManufacturerData()
+ }
+ }
+
+ private fun showDialogForServiceUuid() {
+ val editText = EditText(requireActivity())
+ editText.hint = getString(R.string.uuid_or_service_name)
+
+ AlertDialog.Builder(requireContext())
+ .setTitle(getString(R.string.service_uuid))
+ .setViewEditText(editText)
+ .setPositiveButton(getString(R.string.add)) { _, _ ->
+ val editTextInput = editText.text.toString()
+
+ advertiserViewModel.serviceUuids.add(UUID.fromString(editTextInput))
+ refreshAdvertiseData()
+ }
+ .setNegativeButton(getString(R.string.cancel), null)
+ .create()
+ .show()
+ }
+
+ private fun showDialogForServiceData() {
+ val view = layoutInflater.inflate(R.layout.dialog_service_data, null)
+ val editTextUuidOrServiceName =
+ view.findViewById<EditText>(R.id.edit_text_uuid_or_service_name)
+ val editTextDataHex = view.findViewById<EditText>(R.id.edit_text_data_hex)
+
+ AlertDialog.Builder(requireContext())
+ .setTitle(getString(R.string.service_data))
+ .setView(view)
+ .setPositiveButton(getString(R.string.add)) { _, _ ->
+ val editTextUuidOrServiceNameInput = editTextUuidOrServiceName.text.toString()
+ val editTextDataHexInput = editTextDataHex.text.toString()
+
+ val serviceData = Pair(
+ UUID.fromString(editTextUuidOrServiceNameInput),
+ editTextDataHexInput.toByteArray()
+ )
+ advertiserViewModel.serviceDatas.add(serviceData)
+ }
+ .setNegativeButton(getString(R.string.cancel), null)
+ .create()
+ .show()
+ }
+
+ private fun showDialogForManufacturerData() {
+ val view = layoutInflater.inflate(R.layout.dialog_manufacturer_data, null)
+ val editText16BitCompanyIdentifier =
+ view.findViewById<EditText>(R.id.edit_text_16_bit_company_identifier)
+ val editTextDataHex = view.findViewById<EditText>(R.id.edit_text_data_hex)
+
+ AlertDialog.Builder(requireContext())
+ .setTitle(getString(R.string.manufacturer_data))
+ .setView(view)
+ .setPositiveButton(getString(R.string.add)) { _, _ ->
+ val editText16BitCompanyIdentifierInput =
+ editText16BitCompanyIdentifier.text.toString()
+ val editTextDataHexInput = editTextDataHex.text.toString()
+
+ val manufacturerData = Pair(
+ editText16BitCompanyIdentifierInput.toInt(),
+ editTextDataHexInput.toByteArray()
+ )
+ advertiserViewModel.manufacturerDatas.add(manufacturerData)
+ }
+ .setNegativeButton(getString(R.string.cancel), null)
+ .create()
+ .show()
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ private fun refreshAdvertiseData() {
+ advertiseDataAdapter?.advertiseData = advertiserViewModel.advertiseData
+ advertiseDataAdapter?.notifyDataSetChanged()
+ }
+
+ private fun onClickRemoveAdvertiseData(index: Int) {
+ advertiserViewModel.removeAdvertiseDataAtIndex(index)
+ advertiseDataAdapter?.advertiseData = advertiserViewModel.advertiseData
+ advertiseDataAdapter?.notifyItemRemoved(index)
+ }
+
+ // Permissions are handled by MainActivity requestBluetoothPermissions
+ @SuppressLint("MissingPermission")
+ private fun startAdvertise() {
+ advertiseJob = advertiseScope.launch {
+ isAdvertising = true
+
+ bluetoothLe.advertise(advertiserViewModel.advertiseParams)
+ .collect {
+ Log.d(TAG, "AdvertiseResult collected: $it")
+
+ when (it) {
+ AdvertiseResult.ADVERTISE_STARTED -> {
+ toast("ADVERTISE_STARTED").show()
+ }
+ AdvertiseResult.ADVERTISE_FAILED_DATA_TOO_LARGE -> {
+ isAdvertising = false
+ toast("ADVERTISE_FAILED_DATA_TOO_LARGE").show()
+ }
+ AdvertiseResult.ADVERTISE_FAILED_FEATURE_UNSUPPORTED -> {
+ isAdvertising = false
+ toast("ADVERTISE_FAILED_FEATURE_UNSUPPORTED").show()
+ }
+ AdvertiseResult.ADVERTISE_FAILED_INTERNAL_ERROR -> {
+ isAdvertising = false
+ toast("ADVERTISE_FAILED_INTERNAL_ERROR").show()
+ }
+ AdvertiseResult.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS -> {
+ isAdvertising = false
+ toast("ADVERTISE_FAILED_TOO_MANY_ADVERTISERS").show()
+ }
+ }
+ }
+ }
}
}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserViewModel.kt
new file mode 100644
index 0000000..f0e4cdd
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserViewModel.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth.integration.testapp.ui.advertiser
+
+import androidx.bluetooth.AdvertiseParams
+import androidx.lifecycle.ViewModel
+import java.util.UUID
+
+class AdvertiserViewModel : ViewModel() {
+
+ private companion object {
+ private const val TAG = "AdvertiserViewModel"
+ }
+
+ var includeDeviceAddress = false
+ var includeDeviceName = false
+ var connectable = false
+ var discoverable = false
+ var timeoutMillis = 0
+ var manufacturerDatas = mutableListOf<Pair<Int, ByteArray>>()
+ var serviceDatas = mutableListOf<Pair<UUID, ByteArray>>()
+ var serviceUuids = mutableListOf<UUID>()
+
+ val advertiseData: List<String>
+ get() = listOf(
+ manufacturerDatas
+ .map { "Manufacturer Data:\n" +
+ "Company ID: 0x${it.first} Data: 0x${it.second.toString(Charsets.UTF_8)}" },
+ serviceDatas
+ .map { "Service Data:\n" +
+ "UUID: ${it.first} Data: 0x${it.second.toString(Charsets.UTF_8)}" },
+ serviceUuids
+ .map { "128-bit Service UUID:\n" +
+ "$it" }
+ ).flatten()
+
+ val advertiseParams: AdvertiseParams
+ get() = AdvertiseParams(
+ includeDeviceAddress,
+ includeDeviceName,
+ connectable,
+ discoverable,
+ timeoutMillis,
+ manufacturerDatas.toMap(),
+ serviceDatas.toMap(),
+ serviceUuids
+ )
+
+ fun removeAdvertiseDataAtIndex(index: Int) {
+ val manufacturerDataSize = manufacturerDatas.size
+ val serviceDataSize = serviceDatas.size
+
+ if (index < manufacturerDataSize) {
+ manufacturerDatas.removeAt(index)
+ } else if (index < serviceDataSize + manufacturerDataSize) {
+ serviceDatas.removeAt(index - manufacturerDataSize)
+ } else {
+ serviceUuids.removeAt(index - manufacturerDataSize - serviceDataSize)
+ }
+ }
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/AlertDialog.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/AlertDialog.kt
new file mode 100644
index 0000000..e5d876d
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/AlertDialog.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth.integration.testapp.ui.common
+
+import android.widget.EditText
+import android.widget.FrameLayout
+import androidx.appcompat.app.AlertDialog
+
+fun AlertDialog.Builder.setViewEditText(editText: EditText): AlertDialog.Builder {
+ val frameLayout = FrameLayout(editText.context)
+ frameLayout.addView(editText)
+ val frameLayoutParams = FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT
+ )
+ frameLayoutParams.setMargins(16.dp, 8.dp, 16.dp, 8.dp)
+ frameLayout.layoutParams = frameLayoutParams
+
+ val container = FrameLayout(editText.context)
+ container.addView(frameLayout)
+
+ setView(container)
+
+ return this
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Fragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Fragment.kt
new file mode 100644
index 0000000..395bd0d7
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Fragment.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth.integration.testapp.ui.common
+
+import android.widget.Toast
+import androidx.fragment.app.Fragment
+
+fun Fragment.toast(msg: String): Toast {
+ return Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT)
+}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Number.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Number.kt
new file mode 100644
index 0000000..a86edb2
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/Number.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.bluetooth.integration.testapp.ui.common
+
+import android.content.res.Resources
+import android.util.TypedValue
+
+val Number.dp
+ get() = TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP,
+ toFloat(),
+ Resources.getSystem().displayMetrics
+ ).toInt()
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
index 919b434..7411f0a 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
@@ -41,7 +41,7 @@
class ScannerFragment : Fragment() {
- companion object {
+ private companion object {
private const val TAG = "ScannerFragment"
}
@@ -58,8 +58,12 @@
private var isScanning: Boolean = false
set(value) {
field = value
- if (value) _binding?.buttonScan?.text = getString(R.string.stop_scanning)
- else _binding?.buttonScan?.text = getString(R.string.start_scanning)
+ if (value) {
+ _binding?.buttonScan?.text = getString(R.string.stop_scanning)
+ } else {
+ _binding?.buttonScan?.text = getString(R.string.start_scanning)
+ scanJob?.cancel()
+ }
}
private var _binding: FragmentScannerBinding? = null
@@ -84,29 +88,30 @@
DividerItemDecoration(context, LinearLayoutManager.VERTICAL)
)
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
+ initData()
binding.buttonScan.setOnClickListener {
if (scanJob?.isActive == true) {
- scanJob?.cancel()
isScanning = false
} else {
startScan()
}
}
+
+ return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
- scanJob?.cancel()
isScanning = false
}
+ private fun initData() {
+ scannerAdapter?.submitList(scannerViewModel.results)
+ scannerAdapter?.notifyItemRangeChanged(0, scannerViewModel.results.size)
+ }
+
private fun startScan() {
// TODO(ofy) Migrate to androidx.bluetooth.BluetoothLe once scan API is in place
val scanSettings = ScanSettings.Builder()
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
index e9ab0e8..7d213fd 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerViewModel.kt
@@ -21,7 +21,7 @@
class ScannerViewModel : ViewModel() {
- companion object {
+ private companion object {
private const val TAG = "ScannerViewModel"
}
diff --git a/bluetooth/integration-tests/testapp/src/main/res/drawable/baseline_clear_24.xml b/bluetooth/integration-tests/testapp/src/main/res/drawable/baseline_clear_24.xml
new file mode 100644
index 0000000..2750a06
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/drawable/baseline_clear_24.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<vector android:height="24dp" android:tint="#000000"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/drawable/grey_rounded_background.xml b/bluetooth/integration-tests/testapp/src/main/res/drawable/grey_rounded_background.xml
new file mode 100644
index 0000000..9cafe24
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/drawable/grey_rounded_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#32000000" />
+ <corners android:radius="16dp" />
+</shape>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_manufacturer_data.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_manufacturer_data.xml
new file mode 100644
index 0000000..e9d1138
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_manufacturer_data.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="16dp"
+ android:paddingTop="8dp"
+ android:paddingEnd="16dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="0x"
+ android:textColor="@color/black"
+ android:textSize="21sp"
+ tools:ignore="HardcodedText" />
+
+ <EditText
+ android:id="@+id/edit_text_16_bit_company_identifier"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:hint="@string/sixteen_bit_company_identifier"
+ android:inputType="text" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="0x"
+ android:textColor="@color/black"
+ android:textSize="21sp"
+ tools:ignore="HardcodedText" />
+
+ <EditText
+ android:id="@+id/edit_text_data_hex"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:hint="@string/data_hex"
+ android:inputType="text" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_service_data.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_service_data.xml
new file mode 100644
index 0000000..0c91f3c
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/dialog_service_data.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="16dp"
+ android:paddingTop="8dp"
+ android:paddingEnd="16dp">
+
+ <EditText
+ android:id="@+id/edit_text_uuid_or_service_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/uuid_or_service_name"
+ android:inputType="text" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="0x"
+ android:textColor="@color/black"
+ android:textSize="21sp"
+ tools:ignore="HardcodedText" />
+
+ <EditText
+ android:id="@+id/edit_text_data_hex"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="4dp"
+ android:hint="@string/data_hex"
+ android:inputType="text" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml
index 14e7b3e..c6e37d3 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/fragment_advertiser.xml
@@ -16,7 +16,112 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <TextView
+ android:id="@+id/text_view_configure_advertising_packet"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:text="@string/configure_advertising_packet"
+ android:textColor="@color/black"
+ android:textSize="21sp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/text_input_layout_display_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/display_name"
+ app:layout_constraintTop_toBottomOf="@+id/text_view_configure_advertising_packet">
+
+ <com.google.android.material.textfield.TextInputEditText
+ android:id="@+id/text_input_edit_text_display_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="text"
+ android:maxLines="1" />
+
+ </com.google.android.material.textfield.TextInputLayout>
+
+ <CheckBox
+ android:id="@+id/check_box_include_device_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="8dp"
+ android:text="@string/include_device_name"
+ app:layout_constraintTop_toBottomOf="@+id/text_input_layout_display_name" />
+
+ <CheckBox
+ android:id="@+id/check_box_connectable"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:text="@string/connectable"
+ app:layout_constraintTop_toBottomOf="@+id/check_box_include_device_name" />
+
+ <CheckBox
+ android:id="@+id/check_box_discoverable"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:text="@string/discoverable"
+ app:layout_constraintTop_toBottomOf="@+id/check_box_connectable" />
+
+ <TextView
+ android:id="@+id/text_view_advertising_data"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:layout_marginEnd="8dp"
+ android:padding="8dp"
+ android:text="@string/advertising_data"
+ android:textColor="@color/black"
+ android:textSize="21sp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/check_box_discoverable" />
+
+ <Button
+ android:id="@+id/button_add_data"
+ style="@style/Widget.AppCompat.Button.Borderless"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dp"
+ android:text="@string/add_data"
+ android:textColor="@color/purple_500"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/text_view_advertising_data" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recycler_view_advertise_data"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ app:layoutManager="LinearLayoutManager"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/button_add_data"
+ tools:itemCount="3"
+ tools:listitem="@layout/item_advertiser_data" />
+
+ <View
+ android:id="@+id/view_overlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/black_alpha_50"
+ android:clickable="true"
+ android:visibility="gone" />
+
+ <Button
+ android:id="@+id/button_advertise"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="16dp"
+ android:text="@string/start_advertising"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/layout/item_advertiser_data.xml b/bluetooth/integration-tests/testapp/src/main/res/layout/item_advertiser_data.xml
new file mode 100644
index 0000000..031bd18
--- /dev/null
+++ b/bluetooth/integration-tests/testapp/src/main/res/layout/item_advertiser_data.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginBottom="4dp"
+ android:background="@drawable/grey_rounded_background"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:padding="4dp">
+
+ <TextView
+ android:id="@+id/text_view_data"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:padding="8dp"
+ android:textColor="@color/black"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/button_add_data"
+ tools:text="16-Bit Service UUID: 0x1800" />
+
+ <ImageButton
+ android:id="@+id/image_button_clear"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/baseline_clear_24"
+ android:contentDescription="@string/clear_data" />
+
+</LinearLayout>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml b/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
index 6d70d3a..a7e6ba3 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/colors.xml
@@ -22,4 +22,5 @@
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
+ <color name="black_alpha_50">#80000000</color>
</resources>
diff --git a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
index 0576493..5707c81 100644
--- a/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
+++ b/bluetooth/integration-tests/testapp/src/main/res/values/donottranslate-strings.xml
@@ -27,6 +27,26 @@
<string name="scan_result_icon">Scan Result Icon</string>
<string name="connect">Connect</string>
+ <!-- Advertiser -->
+ <string name="configure_advertising_packet">Configure Advertising Packet</string>
+ <string name="display_name">Display Name</string>
+ <string name="include_device_name">Include Device Name</string>
+ <string name="connectable">Connectable</string>
+ <string name="discoverable">Discoverable</string>
+ <string name="advertising_data">Advertising Data</string>
+ <string name="add_data">Add Data</string>
+ <string name="start_advertising">Start Advertising</string>
+ <string name="stop_advertising">Stop Advertising</string>
+ <string name="service_uuid">Service UUID</string>
+ <string name="uuid_or_service_name">UUID or service name</string>
+ <string name="service_data">Service Data</string>
+ <string name="data_hex">Data (HEX)</string>
+ <string name="manufacturer_data">Manufacturer Data</string>
+ <string name="sixteen_bit_company_identifier">16-bit Company Identifier</string>
+ <string name="add">Add</string>
+ <string name="cancel">Cancel</string>
+ <string name="clear_data">Clear Data</string>
+
<string name="scan_using_androidx_bluetooth">Scan using AndroidX Bluetooth APIs</string>
<string name="scan_start_message">Scan started. Results are in Logcat</string>
diff --git a/build.gradle b/build.gradle
index 3a6b8e5..fc4788f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -25,3 +25,9 @@
apply from: "buildSrc/dependencies.gradle"
apply plugin: AndroidXRootPlugin
+
+// workaround for https://github.com/gradle/gradle/issues/24822
+if (project.hasProperty("androidx.update.signatures")) {
+ apply plugin: "java-library"
+ apply from: "buildSrc/shared-dependencies.gradle"
+}
diff --git a/buildSrc-tests/project-subsets/build.gradle b/buildSrc-tests/project-subsets/build.gradle
deleted file mode 100644
index 3ee8f3d..0000000
--- a/buildSrc-tests/project-subsets/build.gradle
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-plugins {
- id("AndroidXPlugin")
- id("kotlin")
-}
-
-dependencies {
- implementation gradleTestKit()
- testImplementation libs.junit
-}
-tasks["test"].configure { t ->
- // The output of this task can potentially depend on the contents of settings.gradle
- // and any files referenced by it, including every build.gradle and any scripts or plugins they
- // apply too. We don't have a convenient way to identify the true inputs here, so we always
- // run this task and leave details around incrementality up to the Gradle builds that we spawn
- t.outputs.upToDateWhen { false }
-}
-
diff --git a/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt b/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
deleted file mode 100644
index 5bfe120..0000000
--- a/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build
-
-import org.gradle.testkit.runner.GradleRunner
-import org.junit.Test
-import java.io.File
-
-/**
- * This class tests that each of the project subsets defined in settings.gradle can be built
- * successfully and does not involve a project that attempts to reference
- * another project defined only in a different subset, b/172277767 .
- *
- * This is implemented using the Gradle TestKit so it can be
- * run in parallel with other tasks, b/180012150 .
- */
-public class ProjectSubsetsTest {
- @Test
- fun testSubsetMain() {
- validateSubset("main")
- }
-
- @Test
- fun testSubsetCamera() {
- validateSubset("camera")
- }
-
- @Test
- fun testSubsetCompose() {
- validateSubset("compose")
- }
-
- @Test
- fun testSubsetFlan() {
- validateSubset("flan")
- }
-
- @Test
- fun testSubsetMedia() {
- validateSubset("media")
- }
-
- @Test
- fun testSubsetWear() {
- validateSubset("wear")
- }
-
- @Test
- fun testSubsetGlance() {
- validateSubset("glance")
- }
-
- @Test
- fun testSubsetTools() {
- validateSubset("tools")
- }
-
- @Test
- fun testSubsetKmp() {
- validateSubset("kmp")
- }
-
- @Test
- fun testSubsetNative() {
- validateSubset("native")
- }
-
- @Test
- fun testSubsetWindow() {
- validateSubset("window")
- }
- /**
- * Validates a specific project subset
- */
- fun validateSubset(name: String) {
- val projectDir = File("../..").normalize()
- var outDir = System.getenv("OUT_DIR")
- if (outDir == null || outDir == "") {
- outDir = File(projectDir, "../../out").normalize().toString()
- }
- // --dependency-verification=off is set because we don't have to do validation of
- // dependencies during these tests, it is already handled by the main build.
- // Having it validate here breaks in androidx-studio-integration case where we
- // might get new dependencies from AGP that are missinng signatures.
-
- // Run buildOnServer to validate project dependencies and constraints
- GradleRunner.create()
- .withProjectDir(projectDir)
- .withArguments(
- "-Pandroidx.projects=$name", "buildOnServer", "-m", "--dependency-verification=off"
- )
- .withTestKitDir(File(outDir, ".gradle-testkit"))
- .build(); // fails the test if the build fails
- }
-}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
index 1d529cd..32f63ba 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
@@ -153,6 +153,7 @@
error.add("ComposableLambdaParameterPosition")
error.add("CompositionLocalNaming")
error.add("ComposableModifierFactory")
+ error.add("AutoboxingStateValueProperty")
error.add("InvalidColorHexValue")
error.add("MissingColorAlphaChannel")
error.add("ModifierFactoryReturnType")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt
index d373a4f..f6ed376 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXGradleProperties.kt
@@ -152,6 +152,11 @@
*/
const val ALLOW_CUSTOM_COMPILE_SDK = "androidx.allowCustomCompileSdk"
+/**
+ * Whether to update gradle signature verification metadata
+ */
+const val UPDATE_SIGNATURES = "androidx.update.signatures"
+
val ALL_ANDROIDX_PROPERTIES = setOf(
ADD_GROUP_CONSTRAINTS,
ALTERNATIVE_PROJECT_URL,
@@ -179,7 +184,8 @@
ENABLED_KMP_TARGET_PLATFORMS,
ALLOW_MISSING_LINT_CHECKS_PROJECT,
XCODEGEN_DOWNLOAD_URI,
- ALLOW_CUSTOM_COMPILE_SDK
+ ALLOW_CUSTOM_COMPILE_SDK,
+ UPDATE_SIGNATURES
)
/**
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt b/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
index 66d49df..e43634f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/uptodatedness/TaskUpToDateValidator.kt
@@ -136,7 +136,6 @@
// Additional tasks that are expected to be temporarily out-of-date after running once
// Tasks in this set we don't even try to rerun, because they're known to be unnecessary
val DONT_TRY_RERUNNING_TASKS = setOf(
- ":buildSrc-tests:project-subsets:test",
"listTaskOutputs",
"tasks",
diff --git a/buildSrc/shared-dependencies.gradle b/buildSrc/shared-dependencies.gradle
new file mode 100644
index 0000000..1b67981
--- /dev/null
+++ b/buildSrc/shared-dependencies.gradle
@@ -0,0 +1,50 @@
+// This file applies dependencies common to projects in buildSrc
+
+apply from: "${buildscript.sourceFile.parent}/kotlin-dsl-dependency.gradle"
+dependencies {
+
+ // Gradle APIs
+ implementation(gradleApi())
+ compileOnly(findGradleKotlinDsl())
+
+ // Android Gradle Plugin APIs used by Stable AIDL
+ implementation(libs.androidGradlePluginApi)
+
+ // Plugins we use and configure
+ implementation(libs.androidGradlePluginz)
+ implementation(libs.androidToolsCommon) // for com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
+ implementation(libs.androidToolsRepository) // com.android.repository for Stable AIDL plugin
+ implementation(libs.androidToolsSdkCommon) // com.android.ide.common for Stable AIDL plugin
+ implementation(libs.kotlinGradlePluginz)
+
+ // variety of json parsers
+ implementation(libs.gson)
+ implementation(libs.jsonSimple)
+
+ // XML parsers used in MavenUploadHelper.kt
+ implementation(libs.dom4j) {
+ // Optional dependency where Ivy fails to parse the POM file.
+ exclude(group:"net.java.dev.msv", module:"xsdlib")
+ }
+ implementation(libs.xerces)
+
+ implementation(libs.shadow) // used by BundleInsideHelper.kt
+ implementation(libs.apacheAnt) // used in AarManifestTransformerTask.kt for unziping
+ implementation(libs.toml)
+ implementation(libs.apacheCommonIo) // used in CheckApiEquivalenceTask.kt
+ implementation(libs.dexMemberList) // used in ReportLibraryMetricsTask.kt
+
+ implementation(libs.protobufGradlePluginz) // needed to compile inspection plugin
+ implementation(libs.kotlinPoet) // needed to compile material-icon-generator
+ implementation(libs.xmlpull) // needed to compile material-icon-generator
+
+ implementation(libs.protobuf) // needed to compile baseline-profile gradle plugins
+ implementation(libs.agpTestingPlatformCoreProto) // needed to compile baseline-profile gradle plugins
+
+ // dependencies that aren't used by buildSrc directly but that we resolve here so that the
+ // root project doesn't need to re-resolve them and their dependencies on every build
+ runtimeOnly(libs.hiltAndroidGradlePluginz)
+ runtimeOnly(libs.javapoet) // for hiltAndroidGradlePluginz to workaround https://github.com/google/dagger/issues/3068
+ runtimeOnly(libs.kspGradlePluginz)
+ runtimeOnly(libs.wireGradlePluginz)
+}
diff --git a/buildSrc/shared.gradle b/buildSrc/shared.gradle
index 6cb909a..b342c0b 100644
--- a/buildSrc/shared.gradle
+++ b/buildSrc/shared.gradle
@@ -1,6 +1,5 @@
-
+// This file applies configuration common to projects in buildSrc
apply plugin: "kotlin"
-apply from: "../kotlin-dsl-dependency.gradle"
apply plugin: "java-gradle-plugin"
buildscript {
@@ -14,53 +13,10 @@
dependencies {
implementation(project(":jetpad-integration"))
-
- // Gradle APIs
- implementation(gradleApi())
- compileOnly(findGradleKotlinDsl())
-
- // Android Gradle Plugin APIs used by Stable AIDL
- implementation(libs.androidGradlePluginApi)
-
- // Plugins we use and configure
- implementation(libs.androidGradlePluginz)
- implementation(libs.androidToolsCommon) // for com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
- implementation(libs.androidToolsRepository) // com.android.repository for Stable AIDL plugin
- implementation(libs.androidToolsSdkCommon) // com.android.ide.common for Stable AIDL plugin
- implementation(libs.kotlinGradlePluginz)
-
- // variety of json parsers
- implementation(libs.gson)
- implementation(libs.jsonSimple)
-
- // XML parsers used in MavenUploadHelper.kt
- implementation(libs.dom4j) {
- // Optional dependency where Ivy fails to parse the POM file.
- exclude(group:"net.java.dev.msv", module:"xsdlib")
- }
- implementation(libs.xerces)
-
- implementation(libs.shadow) // used by BundleInsideHelper.kt
- implementation(libs.apacheAnt) // used in AarManifestTransformerTask.kt for unziping
- implementation(libs.toml)
- implementation(libs.apacheCommonIo) // used in CheckApiEquivalenceTask.kt
- implementation(libs.dexMemberList) // used in ReportLibraryMetricsTask.kt
-
- implementation(libs.protobufGradlePluginz) // needed to compile inspection plugin
- implementation(libs.kotlinPoet) // needed to compile material-icon-generator
- implementation(libs.xmlpull) // needed to compile material-icon-generator
-
- implementation(libs.protobuf) // needed to compile baseline-profile gradle plugins
- implementation(libs.agpTestingPlatformCoreProto) // needed to compile baseline-profile gradle plugins
-
- // dependencies that aren't used by buildSrc directly but that we resolve here so that the
- // root project doesn't need to re-resolve them and their dependencies on every build
- runtimeOnly(libs.hiltAndroidGradlePluginz)
- runtimeOnly(libs.javapoet) // for hiltAndroidGradlePluginz to workaround https://github.com/google/dagger/issues/3068
- runtimeOnly(libs.kspGradlePluginz)
- runtimeOnly(libs.wireGradlePluginz)
}
+apply from: "../shared-dependencies.gradle"
+
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
diff --git a/busytown/androidx_host_tests.sh b/busytown/androidx_host_tests.sh
index 00ba171..bba9e74 100755
--- a/busytown/androidx_host_tests.sh
+++ b/busytown/androidx_host_tests.sh
@@ -5,10 +5,9 @@
cd "$(dirname $0)"
-impl/build.sh test linuxX64Test \
+impl/build.sh test \
-Pandroidx.ignoreTestFailures \
-Pandroidx.displayTestOutput=false \
- -Pandroidx.enabled.kmp.target.platforms=+native \
"$@"
echo "Completing $0 at $(date)"
diff --git a/busytown/androidx_host_tests_max_dep_versions.sh b/busytown/androidx_host_tests_max_dep_versions.sh
index a56dbc4..ef49669 100755
--- a/busytown/androidx_host_tests_max_dep_versions.sh
+++ b/busytown/androidx_host_tests_max_dep_versions.sh
@@ -5,9 +5,9 @@
cd "$(dirname $0)"
-impl/build.sh test linuxX64Test -Pandroidx.useMaxDepVersions \
+impl/build.sh test \
+ -Pandroidx.useMaxDepVersions \
-Pandroidx.displayTestOutput=false \
- -Pandroidx.enabled.kmp.target.platforms=+native \
-Pandroidx.ignoreTestFailures "$@"
echo "Completing $0 at $(date)"
diff --git a/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt b/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt
index 6b10990..9d11137 100644
--- a/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt
+++ b/camera/camera-camera2-pipe-integration/api/public_plus_experimental_current.txt
@@ -28,7 +28,7 @@
@RequiresApi(21) public static final class Camera2Interop.Extender<T> {
ctor public Camera2Interop.Extender(androidx.camera.core.ExtendableBuilder<T> baseBuilder);
- method public <ValueT> androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT? value);
+ method public <ValueT> androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT value);
method public androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setDeviceStateCallback(android.hardware.camera2.CameraDevice.StateCallback stateCallback);
method @RequiresApi(28) public androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setPhysicalCameraId(String cameraId);
method public androidx.camera.camera2.pipe.integration.interop.Camera2Interop.Extender<T> setSessionCaptureCallback(android.hardware.camera2.CameraCaptureSession.CaptureCallback captureCallback);
@@ -44,7 +44,7 @@
ctor public CaptureRequestOptions.Builder();
method public androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions build();
method public <ValueT> androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions.Builder clearCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key);
- method public <ValueT> androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT? value);
+ method public <ValueT> androidx.camera.camera2.pipe.integration.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT> key, ValueT value);
}
@kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalCamera2Interop {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
index a741f20..17ecd63 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraInfoAdapter.kt
@@ -195,8 +195,10 @@
// TODO: use DynamicRangesCompat instead after it is migrates from camera-camera2.
if (Build.VERSION.SDK_INT >= 33) {
val availableProfiles = cameraProperties.metadata[
- CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES]!!
- return profileSetToDynamicRangeSet(availableProfiles.supportedProfiles)
+ CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES]
+ if (availableProfiles != null) {
+ return profileSetToDynamicRangeSet(availableProfiles.supportedProfiles)
+ }
}
return setOf(DynamicRange.SDR)
}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt
index c46831d..d80d27a 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/CameraQuirks.kt
@@ -95,6 +95,9 @@
if (CaptureSessionStuckQuirk.isEnabled()) {
quirks.add(CaptureSessionStuckQuirk())
}
+ if (FinalizeSessionOnCloseQuirk.isEnabled()) {
+ quirks.add(FinalizeSessionOnCloseQuirk())
+ }
Quirks(quirks)
}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/FinalizeSessionOnCloseQuirk.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/FinalizeSessionOnCloseQuirk.kt
new file mode 100644
index 0000000..95a6727
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/FinalizeSessionOnCloseQuirk.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.camera2.pipe.integration.compat.quirk
+
+import android.annotation.SuppressLint
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior
+import androidx.camera.core.impl.Quirk
+
+/**
+ * A quirk that finalizes [androidx.camera.camera2.pipe.compat.CaptureSessionState] when the
+ * CameraGraph is stopped or closed.
+ *
+ * QuirkSummary
+ * - Bug Id: 277310425
+ * - Description: When CameraX sets up its video recorder, it waits for the previous Surfaces to be
+ * released before setting them in the new CameraGraph. However, CameraPipe would
+ * also wait for the Surfaces to be set before it creates a new capture session and
+ * finalize the previous session, and therefore not releasing the Surfaces. This
+ * essentially creates a deadlock, and this quirk would enable a behavior in
+ * CameraPipe such that the current session gets finalized either immediately or on a
+ * timeout after the CameraGraph is stopped or closed.
+ * - Device(s): All devices.
+ */
+@SuppressLint("CameraXQuirksClassDetector")
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class FinalizeSessionOnCloseQuirk : Quirk {
+ companion object {
+ fun isEnabled() = true
+
+ fun getBehavior() =
+ if (Build.BRAND == "google") {
+ // Finalize immediately for devices that allow immediate Surface reuse.
+ FinalizeSessionOnCloseBehavior.IMMEDIATE
+ } else {
+ FinalizeSessionOnCloseBehavior.TIMEOUT
+ }
+ }
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt
index b827dcd..0c5a985 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/CameraConfig.kt
@@ -38,6 +38,7 @@
import androidx.camera.camera2.pipe.integration.compat.ZoomCompat
import androidx.camera.camera2.pipe.integration.compat.quirk.CameraQuirks
import androidx.camera.camera2.pipe.integration.compat.quirk.CaptureSessionStuckQuirk
+import androidx.camera.camera2.pipe.integration.compat.quirk.FinalizeSessionOnCloseQuirk
import androidx.camera.camera2.pipe.integration.impl.CameraPipeCameraProperties
import androidx.camera.camera2.pipe.integration.impl.CameraProperties
import androidx.camera.camera2.pipe.integration.impl.ComboRequestListener
@@ -156,7 +157,14 @@
Log.debug { "CameraPipe should be enabling CaptureSessionStuckQuirk" }
}
// TODO(b/276354253): Set quirkWaitForRepeatingRequestOnDisconnect flag for overrides.
- return CameraGraph.Flags()
+
+ // TODO(b/277310425): When creating a CameraGraph, this flag should be turned OFF when
+ // this behavior is not needed based on the use case interaction and the device on
+ // which the test is running.
+ val quirkFinalizeSessionOnCloseBehavior = FinalizeSessionOnCloseQuirk.getBehavior()
+ return CameraGraph.Flags(
+ quirkFinalizeSessionOnCloseBehavior = quirkFinalizeSessionOnCloseBehavior,
+ )
}
}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt
index a4635da..d8e75a8 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/config/UseCaseCameraConfig.kt
@@ -138,6 +138,9 @@
}
// Build up a config (using TEMPLATE_PREVIEW by default)
+ // TODO(b/277310425): Turn off CameraGraph.Flags.quirkFinalizeSessionOnCloseBehavior when
+ // it's not needed. This should be needed only when all use cases are detached (with
+ // VideoCapture) on devices where Surfaces cannot be released immediately.
val graph = cameraPipe.create(
CameraGraph.Config(
camera = cameraConfig.cameraId,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
index 00d5f2c4..ddba7d3 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
@@ -78,7 +78,7 @@
override fun onSuggestedStreamSpecUpdated(suggestedStreamSpec: StreamSpec): StreamSpec {
updateSessionConfig(createPipeline(meteringSurfaceSize).build())
notifyActive()
- return StreamSpec.builder(meteringSurfaceSize).build()
+ return suggestedStreamSpec.toBuilder().setResolution(meteringSurfaceSize).build()
}
override fun onUnbind() {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt
index 60e6949..6de5177 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraError.kt
@@ -172,4 +172,7 @@
}
// TODO(b/276918807): When we have CameraProperties, handle the exception on a more granular level.
-class DoNotDisturbException(message: String) : RuntimeException(message)
\ No newline at end of file
+class DoNotDisturbException(message: String) : RuntimeException(message)
+
+// An exception indicating that the CameraDevice.close() call has stalled.
+class CameraCloseStallException(message: String) : RuntimeException(message)
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt
index b1dda57..7e5ce4b 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/CameraGraph.kt
@@ -26,6 +26,7 @@
import androidx.annotation.RequiresApi
import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_FRAME_LIMIT
import androidx.camera.camera2.pipe.CameraGraph.Constants3A.DEFAULT_TIME_LIMIT_NS
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior.Companion.OFF
import androidx.camera.camera2.pipe.GraphState.GraphStateStarting
import androidx.camera.camera2.pipe.GraphState.GraphStateStopped
import androidx.camera.camera2.pipe.GraphState.GraphStateStopping
@@ -151,7 +152,36 @@
* - API levels: All
*/
val quirkWaitForRepeatingRequestOnDisconnect: Boolean? = null,
- )
+
+ val quirkFinalizeSessionOnCloseBehavior: FinalizeSessionOnCloseBehavior = OFF,
+ ) {
+
+ @JvmInline
+ value class FinalizeSessionOnCloseBehavior private constructor(val value: Int) {
+ companion object {
+ /**
+ * OFF indicates that the CameraGraph only finalizes capture session under regular
+ * conditions, i.e., when the camera device is closed, or when a new capture
+ * session is created.
+ */
+ val OFF = FinalizeSessionOnCloseBehavior(0)
+
+ /**
+ * IMMEDIATE indicates that the CameraGraph will finalize the current session
+ * immediately when the CameraGraph is stopped or closed. This should be the
+ * default behavior for devices that allows for immediate Surface reuse.
+ */
+ val IMMEDIATE = FinalizeSessionOnCloseBehavior(1)
+
+ /**
+ * TIMEOUT indicates that the CameraGraph will finalize the current session on a 2s
+ * timeout when the CameraGraph is stopped or closed. This should only be enabled
+ * for devices that require waiting for Surfaces to be released.
+ */
+ val TIMEOUT = FinalizeSessionOnCloseBehavior(2)
+ }
+ }
+ }
enum class OperatingMode {
NORMAL,
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
index e1772d1..35995c4 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CameraController.kt
@@ -101,6 +101,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ config.flags.quirkFinalizeSessionOnCloseBehavior,
scope
)
currentSession = session
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt
index fb1663d..30f87b1 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2DeviceCloser.kt
@@ -21,6 +21,7 @@
import android.hardware.camera2.CameraDevice
import android.view.Surface
import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraCloseStallException
import androidx.camera.camera2.pipe.CameraId
import androidx.camera.camera2.pipe.core.Debug
import androidx.camera.camera2.pipe.core.Log
@@ -29,6 +30,8 @@
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.atomicfu.atomic
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeoutOrNull
internal interface Camera2DeviceCloser {
fun closeCamera(
@@ -81,7 +84,13 @@
}
}
Log.debug { "Closing $cameraDevice" }
- cameraDevice.closeWithTrace()
+ runBlocking {
+ withTimeoutOrNull(2000L) {
+ cameraDevice.closeWithTrace()
+ } ?: {
+ throw CameraCloseStallException("The camera close call failed to return in 2000ms")
+ }
+ }
if (camera2Quirks.shouldWaitForCameraDeviceOnClosed(cameraId)) {
Log.debug { "Waiting for camera device to be completely closed" }
if (androidCameraState.awaitCameraDeviceClosed(timeoutMillis = 2000)) {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt
index 9580eef..0852ebf 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionState.kt
@@ -22,6 +22,7 @@
import android.view.Surface
import androidx.annotation.GuardedBy
import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior
import androidx.camera.camera2.pipe.CameraSurfaceManager
import androidx.camera.camera2.pipe.StreamId
import androidx.camera.camera2.pipe.core.Debug
@@ -35,6 +36,7 @@
import java.util.Collections.synchronizedMap
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
internal val captureSessionDebugIds = atomic(0)
@@ -63,6 +65,7 @@
private val captureSequenceProcessorFactory: Camera2CaptureSequenceProcessorFactory,
private val cameraSurfaceManager: CameraSurfaceManager,
private val timeSource: TimeSource,
+ private val finalizeSessionOnCloseBehavior: FinalizeSessionOnCloseBehavior,
private val scope: CoroutineScope
) : CameraCaptureSessionWrapper.StateCallback {
private val debugId = captureSessionDebugIds.incrementAndGet()
@@ -182,7 +185,7 @@
Log.debug { "$this Finalizing Session" }
Debug.traceStart { "$this#onSessionFinalized" }
disconnect()
- finalizeSession()
+ finalizeSession(0L)
Debug.traceStop()
}
}
@@ -294,30 +297,52 @@
Debug.traceStop()
}
- var shouldFinalizeSession: Boolean
+ var shouldFinalizeSession = false
+ var finalizeSessionDelayMs = 0L
synchronized(lock) {
// If the CameraDevice is never opened, the session will never be created. For cleanup
// reasons, make sure the session is finalized after shutdown if the cameraDevice was
// never set.
- shouldFinalizeSession = state != State.CLOSED &&
- (_cameraDevice == null || !hasAttemptedCaptureSession)
+ if (state != State.CLOSED) {
+ if (_cameraDevice == null || !hasAttemptedCaptureSession) {
+ shouldFinalizeSession = true
+ } else if (finalizeSessionOnCloseBehavior ==
+ FinalizeSessionOnCloseBehavior.IMMEDIATE
+ ) {
+ shouldFinalizeSession = true
+ } else if (finalizeSessionOnCloseBehavior ==
+ FinalizeSessionOnCloseBehavior.TIMEOUT
+ ) {
+ shouldFinalizeSession = true
+ finalizeSessionDelayMs = 2000L
+ }
+ }
_cameraDevice = null
state = State.CLOSED
}
if (shouldFinalizeSession) {
- finalizeSession()
+ finalizeSession(finalizeSessionDelayMs)
}
}
- private fun finalizeSession() {
- val tokenList =
- synchronized(lock) {
- val tokens = _surfaceTokenMap.values.toList()
- _surfaceTokenMap.clear()
- tokens
+ private fun finalizeSession(delayMs: Long = 0L) {
+ if (delayMs != 0L) {
+ scope.launch {
+ Log.debug { "Finalizing $this in $delayMs ms" }
+ delay(delayMs)
+ finalizeSession(0L)
}
- tokenList.forEach { it.close() }
+ } else {
+ Log.debug { "Finalizing $this" }
+ val tokenList =
+ synchronized(lock) {
+ val tokens = _surfaceTokenMap.values.toList()
+ _surfaceTokenMap.clear()
+ tokens
+ }
+ tokenList.forEach { it.close() }
+ }
}
private fun finalizeOutputsIfAvailable(retryAllowed: Boolean = true) {
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt
index 475d2fb..3635a7c 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt
@@ -128,6 +128,7 @@
},
CameraSurfaceManager(),
SystemTimeSource(),
+ CameraGraph.Flags.FinalizeSessionOnCloseBehavior.OFF,
this
)
)
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt
index 5298f07..45f4731 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionStateTest.kt
@@ -19,6 +19,7 @@
import android.graphics.SurfaceTexture
import android.os.Build
import android.view.Surface
+import androidx.camera.camera2.pipe.CameraGraph.Flags.FinalizeSessionOnCloseBehavior
import androidx.camera.camera2.pipe.CameraSurfaceManager
import androidx.camera.camera2.pipe.CaptureSequenceProcessor
import androidx.camera.camera2.pipe.Request
@@ -90,6 +91,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ FinalizeSessionOnCloseBehavior.OFF,
this
)
// When disconnect is called first
@@ -112,6 +114,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ FinalizeSessionOnCloseBehavior.OFF,
this
)
@@ -139,6 +142,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ FinalizeSessionOnCloseBehavior.OFF,
this
)
@@ -172,6 +176,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ FinalizeSessionOnCloseBehavior.OFF,
this
)
// When surfaces are configured
@@ -195,6 +200,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ FinalizeSessionOnCloseBehavior.OFF,
this
)
// When surfaces are configured
@@ -218,6 +224,7 @@
captureSequenceProcessorFactory,
cameraSurfaceManager,
timeSource,
+ FinalizeSessionOnCloseBehavior.OFF,
this
)
// When surfaces are configured
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java
index 286b8a3..9503797 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompat.java
@@ -349,6 +349,53 @@
}
/**
+ * Return current dynamic range profile.
+ *
+ * <p>On API level 32 and lower, this value will return what is set by
+ * {@link #setDynamicRangeProfile(long)}, but when the output configuration is used in a
+ * {@link SessionConfigurationCompat} that is used to
+ * {@link androidx.camera.camera2.internal.compat.CameraDeviceCompat#createCaptureSession(
+ * SessionConfigurationCompat) create a capture session}, the value will be ignored and
+ * camera will run the output as {@code STANDARD} dynamic range.
+ */
+ public long getDynamicRangeProfile() {
+ return mImpl.getDynamicRangeProfile();
+ }
+
+ /**
+ * Set a specific device supported dynamic range profile.
+ *
+ * <p>Clients can choose from any profile advertised as supported in
+ * {@link
+ * android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES}
+ * queried using
+ * {@link android.hardware.camera2.params.DynamicRangeProfiles#getSupportedProfiles()}. If this
+ * is not explicitly set, then the default profile will be
+ * {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD}.
+ *
+ * <p>Do note that invalid combinations between the registered output surface pixel format and
+ * the configured dynamic range profile will cause capture session initialization failure.
+ * Invalid combinations include any 10-bit dynamic range profile advertised in
+ * {@link android.hardware.camera2.params.DynamicRangeProfiles#getSupportedProfiles()}
+ * combined with an output Surface pixel format
+ * different from {@link android.graphics.ImageFormat#PRIVATE} (the default for Surfaces
+ * initialized by {@link android.view.SurfaceView}, {@link android.view.TextureView},
+ * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec} etc.) or
+ * {@link android.graphics.ImageFormat#YCBCR_P010}.
+ *
+ * <p>On API level 32 and lower, the only supported dynamic range is
+ * {@link android.hardware.camera2.params.DynamicRangeProfiles#STANDARD}. On those API
+ * levels, any other values will be ignored when the output configuring is used in a
+ * {@link SessionConfigurationCompat} that is used to
+ * {@link androidx.camera.camera2.internal.compat.CameraDeviceCompat#createCaptureSession(
+ * SessionConfigurationCompat) create a capture session}, and the
+ * dynamic range used by the camera will remain {@code STANDARD} dynamic range.
+ */
+ public void setDynamicRangeProfile(long profile) {
+ mImpl.setDynamicRangeProfile(profile);
+ }
+
+ /**
* Set the stream use case associated with this {@link OutputConfigurationCompat}.
*
* Stream use case is used to describe the purpose of the stream, whether it's for live
@@ -452,6 +499,10 @@
int getMaxSharedSurfaceCount();
+ long getDynamicRangeProfile();
+
+ void setDynamicRangeProfile(long profile);
+
void setStreamUseCase(long streamUseCase);
long getStreamUseCase();
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java
index 4198f6c..61540cb 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi24Impl.java
@@ -16,6 +16,7 @@
package androidx.camera.camera2.internal.compat.params;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.view.Surface;
@@ -82,6 +83,16 @@
}
@Override
+ public long getDynamicRangeProfile() {
+ return ((OutputConfigurationParamsApi24) mObject).mDynamicRangeProfile;
+ }
+
+ @Override
+ public void setDynamicRangeProfile(long profile) {
+ ((OutputConfigurationParamsApi24) mObject).mDynamicRangeProfile = profile;
+ }
+
+ @Override
@Nullable
public Surface getSurface() {
return ((OutputConfiguration) getOutputConfiguration()).getSurface();
@@ -112,6 +123,7 @@
@Nullable
String mPhysicalCameraId;
boolean mIsShared;
+ long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
OutputConfigurationParamsApi24(@NonNull OutputConfiguration configuration) {
mOutputConfiguration = configuration;
@@ -127,6 +139,7 @@
return Objects.equals(mOutputConfiguration, otherOutputConfig.mOutputConfiguration)
&& mIsShared == otherOutputConfig.mIsShared
+ && mDynamicRangeProfile == otherOutputConfig.mDynamicRangeProfile
&& Objects.equals(mPhysicalCameraId, otherOutputConfig.mPhysicalCameraId);
}
@@ -141,7 +154,8 @@
// (h * 31) XOR mPhysicalCameraId.hashCode()
h = ((h << 5) - h)
^ (mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
-
+ // (h * 31) XOR mDynamicRangeProfile
+ h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
return h;
}
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java
index f4ccd74..abbdfcd 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi26Impl.java
@@ -17,6 +17,7 @@
package androidx.camera.camera2.internal.compat.params;
import android.annotation.SuppressLint;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.view.Surface;
@@ -118,6 +119,16 @@
return ((OutputConfigurationParamsApi26) mObject).mPhysicalCameraId;
}
+ @Override
+ public long getDynamicRangeProfile() {
+ return ((OutputConfigurationParamsApi26) mObject).mDynamicRangeProfile;
+ }
+
+ @Override
+ public void setDynamicRangeProfile(long profile) {
+ ((OutputConfigurationParamsApi26) mObject).mDynamicRangeProfile = profile;
+ }
+
/**
* Remove a surface from this OutputConfiguration.
*/
@@ -177,6 +188,8 @@
@Nullable
String mPhysicalCameraId;
+ long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
+
OutputConfigurationParamsApi26(@NonNull OutputConfiguration configuration) {
mOutputConfiguration = configuration;
}
@@ -190,6 +203,7 @@
OutputConfigurationParamsApi26 otherOutputConfig = (OutputConfigurationParamsApi26) obj;
return Objects.equals(mOutputConfiguration, otherOutputConfig.mOutputConfiguration)
+ && mDynamicRangeProfile == otherOutputConfig.mDynamicRangeProfile
&& Objects.equals(mPhysicalCameraId, otherOutputConfig.mPhysicalCameraId);
}
@@ -203,7 +217,8 @@
// (h * 31) XOR mPhysicalCameraId.hashCode()
h = ((h << 5) - h)
^ (mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
-
+ // (h * 31) XOR mDynamicRangeProfile
+ h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
return h;
}
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java
index 4d0d30b..6adb087 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi28Impl.java
@@ -16,6 +16,7 @@
package androidx.camera.camera2.internal.compat.params;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.view.Surface;
@@ -24,6 +25,8 @@
import androidx.annotation.RequiresApi;
import androidx.core.util.Preconditions;
+import java.util.Objects;
+
/**
* Implementation of the OutputConfiguration compat methods for API 28 and above.
*/
@@ -31,11 +34,11 @@
class OutputConfigurationCompatApi28Impl extends OutputConfigurationCompatApi26Impl {
OutputConfigurationCompatApi28Impl(@NonNull Surface surface) {
- super(new OutputConfiguration(surface));
+ this(new OutputConfigurationParamsApi28(new OutputConfiguration(surface)));
}
OutputConfigurationCompatApi28Impl(int surfaceGroupId, @NonNull Surface surface) {
- this(new OutputConfiguration(surfaceGroupId, surface));
+ this(new OutputConfigurationParamsApi28(new OutputConfiguration(surfaceGroupId, surface)));
}
OutputConfigurationCompatApi28Impl(@NonNull Object outputConfiguration) {
@@ -45,7 +48,8 @@
@RequiresApi(28)
static OutputConfigurationCompatApi28Impl wrap(
@NonNull OutputConfiguration outputConfiguration) {
- return new OutputConfigurationCompatApi28Impl(outputConfiguration);
+ return new OutputConfigurationCompatApi28Impl(
+ new OutputConfigurationParamsApi28(outputConfiguration));
}
/**
@@ -79,11 +83,56 @@
return null;
}
+ @Override
+ public long getDynamicRangeProfile() {
+ return ((OutputConfigurationParamsApi28) mObject).mDynamicRangeProfile;
+ }
+
+ @Override
+ public void setDynamicRangeProfile(long profile) {
+ ((OutputConfigurationParamsApi28) mObject).mDynamicRangeProfile = profile;
+ }
+
@NonNull
@Override
public Object getOutputConfiguration() {
- Preconditions.checkArgument(mObject instanceof OutputConfiguration);
- return mObject;
+ Preconditions.checkArgument(mObject instanceof OutputConfigurationParamsApi28);
+ return ((OutputConfigurationParamsApi28) mObject).mOutputConfiguration;
+ }
+
+ private static final class OutputConfigurationParamsApi28 {
+ @NonNull
+ final OutputConfiguration mOutputConfiguration;
+
+ long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
+
+ OutputConfigurationParamsApi28(@NonNull OutputConfiguration configuration) {
+ mOutputConfiguration = configuration;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof OutputConfigurationParamsApi28)) {
+ return false;
+ }
+
+ OutputConfigurationParamsApi28 otherOutputConfig = (OutputConfigurationParamsApi28) obj;
+
+ return Objects.equals(mOutputConfiguration, otherOutputConfig.mOutputConfiguration)
+ && mDynamicRangeProfile == otherOutputConfig.mDynamicRangeProfile;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int h = 1;
+ // Strength reduction; in case the compiler has illusions about divisions being faster
+ // (h * 31) XOR mOutputConfiguration.hashCode()
+ h = ((h << 5) - h) ^ mOutputConfiguration.hashCode();
+ // (h * 31) XOR mDynamicRangeProfile
+ h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
+ return h;
+ }
}
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java
index 78e9cab..a2d905b 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatApi33Impl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
+import androidx.core.util.Preconditions;
/**
* Implementation of the OutputConfiguration compat methods for API 33 and above.
@@ -47,6 +48,23 @@
}
@Override
+ public long getDynamicRangeProfile() {
+ return ((OutputConfiguration) getOutputConfiguration()).getDynamicRangeProfile();
+ }
+
+ @Override
+ public void setDynamicRangeProfile(long profile) {
+ ((OutputConfiguration) getOutputConfiguration()).setDynamicRangeProfile(profile);
+ }
+
+ @NonNull
+ @Override
+ public Object getOutputConfiguration() {
+ Preconditions.checkArgument(mObject instanceof OutputConfiguration);
+ return mObject;
+ }
+
+ @Override
public void setStreamUseCase(long streamUseCase) {
if (streamUseCase == OutputConfigurationCompat.STREAM_USE_CASE_NONE) {
return;
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java
index a24552e..ef70b78 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatBaseImpl.java
@@ -18,6 +18,7 @@
import android.annotation.SuppressLint;
import android.graphics.ImageFormat;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.os.Build;
import android.util.Size;
import android.view.Surface;
@@ -144,6 +145,16 @@
return OutputConfigurationParamsApi21.MAX_SURFACES_COUNT;
}
+ @Override
+ public long getDynamicRangeProfile() {
+ return ((OutputConfigurationParamsApi21) mObject).mDynamicRangeProfile;
+ }
+
+ @Override
+ public void setDynamicRangeProfile(long profile) {
+ ((OutputConfigurationParamsApi21) mObject).mDynamicRangeProfile = profile;
+ }
+
/**
* Get the {@link Surface} associated with this {@link OutputConfigurationCompat}.
*/
@@ -230,6 +241,7 @@
@Nullable
String mPhysicalCameraId;
boolean mIsShared = false;
+ long mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
OutputConfigurationParamsApi21(@NonNull Surface surface) {
Preconditions.checkNotNull(surface, "Surface must not be null");
@@ -310,6 +322,7 @@
|| mConfiguredFormat != otherOutputConfig.mConfiguredFormat
|| mConfiguredGenerationId != otherOutputConfig.mConfiguredGenerationId
|| mIsShared != otherOutputConfig.mIsShared
+ || mDynamicRangeProfile != otherOutputConfig.mDynamicRangeProfile
|| !Objects.equals(mPhysicalCameraId, otherOutputConfig.mPhysicalCameraId)) {
return false;
}
@@ -337,7 +350,8 @@
// (h * 31) XOR mPhysicalCameraId.hashCode()
h = ((h << 5) - h)
^ (mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode());
-
+ // (h * 31) XOR mDynamicRangeProfile
+ h = ((h << 5) - h) ^ Long.hashCode(mDynamicRangeProfile);
return h;
}
}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java
index 4c3dead..7b2ad2a 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/params/OutputConfigurationCompatTest.java
@@ -23,6 +23,7 @@
import static org.mockito.Mockito.verify;
import android.graphics.SurfaceTexture;
+import android.hardware.camera2.params.DynamicRangeProfiles;
import android.hardware.camera2.params.OutputConfiguration;
import android.os.Build;
import android.util.Size;
@@ -46,6 +47,8 @@
private static final int TEST_GROUP_ID = 100;
private static final String PHYSICAL_CAMERA_ID = "1";
+ private static final long DYNAMIC_RANGE_PROFILE = DynamicRangeProfiles.HLG10;
+
private static void assumeSurfaceSharingAvailable(
OutputConfigurationCompat outputConfigCompat) {
Assume.assumeTrue("API level does not support surface sharing.",
@@ -235,4 +238,14 @@
verify(outputConfig, times(1)).setPhysicalCameraId(PHYSICAL_CAMERA_ID);
}
+
+ @Test
+ public void canSetDynamicRangeProfile() {
+ OutputConfigurationCompat outputConfigCompat =
+ new OutputConfigurationCompat(mock(Surface.class));
+
+ outputConfigCompat.setDynamicRangeProfile(DYNAMIC_RANGE_PROFILE);
+
+ assertThat(outputConfigCompat.getDynamicRangeProfile()).isEqualTo(DYNAMIC_RANGE_PROFILE);
+ }
}
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt
index 1470829..60d5d804 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt
@@ -71,6 +71,7 @@
class DefaultSurfaceProcessorTest {
companion object {
+ private const val JPEG_QUALITY = 100
private const val WIDTH = 640
private const val HEIGHT = 480
private const val CUSTOM_SHADER_FORMAT = """
@@ -143,7 +144,7 @@
createSurfaceProcessor()
// Act: take a snapshot and then release the processor.
- val snapshotFuture = surfaceProcessor.snapshot()
+ val snapshotFuture = surfaceProcessor.snapshot(JPEG_QUALITY)
surfaceProcessor.release()
// Assert: the snapshot future should receive an exception.
@@ -176,7 +177,7 @@
surfaceProcessor.onOutputSurface(surfaceOutput)
// Act: take a snapshot and draw a Bitmap to the input Surface
- surfaceProcessor.snapshot()
+ surfaceProcessor.snapshot(JPEG_QUALITY)
val inputImage = createBitmap(WIDTH, HEIGHT)
val inputSurface = surfaceRequest.deferrableSurface.surface.get()
val canvas = inputSurface.lockHardwareCanvas()
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index dfc5a4f..27c35c0 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -390,6 +390,8 @@
mMetadataMatchingCaptureCallback = new CameraCaptureCallback() {
};
} else if (isSessionProcessorEnabledInCurrentCamera()) {
+ // TODO: remove this section and the rest of the code where it needs the
+ // isSessionProcessorEnabledInCurrentCamera check.
ImageReaderProxy imageReader;
// SessionProcessor only outputs JPEG format.
if (getImageFormat() == ImageFormat.JPEG) {
@@ -1699,10 +1701,6 @@
// Use old pipeline for custom ImageReader.
return false;
}
- if (isSessionProcessorEnabledInCurrentCamera()) {
- // Use old pipeline when extension is enabled.
- return false;
- }
if (config.getBufferFormat(ImageFormat.JPEG) != ImageFormat.JPEG) {
// Use old pipeline for non-JPEG output format.
@@ -1726,8 +1724,9 @@
Size resolution = streamSpec.getResolution();
checkState(mImagePipeline == null);
- mImagePipeline = new ImagePipeline(config, resolution, getEffect(),
- !requireNonNull(getCamera()).getHasTransform());
+ boolean isVirtualCamera = !requireNonNull(getCamera()).getHasTransform()
+ || isSessionProcessorEnabledInCurrentCamera();
+ mImagePipeline = new ImagePipeline(config, resolution, getEffect(), isVirtualCamera);
if (mTakePictureManager == null) {
// mTakePictureManager is reused when the Surface is reset.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java
index 17c29ae..f381cfc 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/StreamSpec.java
@@ -16,10 +16,12 @@
package androidx.camera.core.impl;
+import android.hardware.camera2.CameraMetadata;
import android.util.Range;
import android.util.Size;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.camera.core.DynamicRange;
@@ -60,6 +62,14 @@
@NonNull
public abstract Range<Integer> getExpectedFrameRateRange();
+ /**
+ * Returns the implementation options associated with this stream
+ * specification.
+ * @return the implementation options for the stream.
+ */
+ @Nullable
+ public abstract Config getImplementationOptions();
+
/** Returns a build for a stream configuration that takes a required resolution. */
@NonNull
public static Builder builder(@NonNull Size resolution) {
@@ -101,6 +111,15 @@
@NonNull
public abstract Builder setExpectedFrameRateRange(@NonNull Range<Integer> range);
+ /**
+ * Sets the implementation options.
+ *
+ * <p>If not set, the default expected frame rate range is
+ * {@link CameraMetadata#SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT}.
+ */
+ @NonNull
+ public abstract Builder setImplementationOptions(@NonNull Config config);
+
/** Builds the stream specification */
@NonNull
public abstract StreamSpec build();
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
index 0a5b262..bfce459 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/DefaultSurfaceProcessor.java
@@ -20,15 +20,19 @@
import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
import static androidx.core.util.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.opengl.Matrix;
import android.os.Handler;
import android.os.HandlerThread;
+import android.util.Pair;
import android.util.Size;
import android.view.Surface;
+import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
@@ -86,7 +90,7 @@
// Only access this on GL thread.
private boolean mIsReleased = false;
// Only access this on GL thread.
- private final List<CallbackToFutureAdapter.Completer<Void>> mPendingSnapshots =
+ private final List<Pair<CallbackToFutureAdapter.Completer<Void>, Integer>> mPendingSnapshots =
new ArrayList<>();
/** Constructs {@link DefaultSurfaceProcessor} with default shaders. */
@@ -178,13 +182,15 @@
@NonNull
@Override
- public ListenableFuture<Void> snapshot() {
+ public ListenableFuture<Void> snapshot(@IntRange(from = 0, to = 100) int jpegQuality) {
return Futures.nonCancellationPropagating(CallbackToFutureAdapter.getFuture(
completer -> {
- executeSafely(() -> mPendingSnapshots.add(completer),
- () -> completer.setException(
- new Exception(
- "Failed to snapshot: OpenGLRenderer not ready.")));
+ Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot =
+ new Pair<>(completer, jpegQuality);
+ executeSafely(
+ () -> mPendingSnapshots.add(pendingSnapshot),
+ () -> completer.setException(new Exception(
+ "Failed to snapshot: OpenGLRenderer not ready.")));
return "DefaultSurfaceProcessor#snapshot";
}));
}
@@ -221,7 +227,12 @@
}
// Execute all pending snapshots.
- takeSnapshotAndDrawJpeg(jpegOutput);
+ try {
+ takeSnapshotAndDrawJpeg(jpegOutput);
+ } catch (RuntimeException e) {
+ // Propagates error back to the app if failed to take snapshot.
+ failAllPendingSnapshots(e);
+ }
}
/**
@@ -237,26 +248,42 @@
// No JPEG Surface, fail all snapshot requests.
if (jpegOutput == null) {
- for (CallbackToFutureAdapter.Completer<Void> completer : mPendingSnapshots) {
- completer.setException(
- new Exception("Failed to snapshot: no JPEG Surface."));
- }
- mPendingSnapshots.clear();
+ failAllPendingSnapshots(new Exception("Failed to snapshot: no JPEG Surface."));
return;
}
- // Get JPEG bytes.
- byte[] jpegBytes = getJpegByteArray(jpegOutput.getSecond(), jpegOutput.getThird());
+ // Get snapshot Bitmap.
+ Bitmap bitmap = getBitmap(jpegOutput.getSecond(), jpegOutput.getThird());
+
// Write to JPEG surface, once for each snapshot request.
- for (CallbackToFutureAdapter.Completer<Void> completer : mPendingSnapshots) {
- writeJpegBytesToSurface(jpegOutput.getFirst(), jpegBytes);
- completer.set(null);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] jpegBytes = null;
+ int jpegQuality = -1;
+ for (Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot :
+ mPendingSnapshots) {
+ if (jpegQuality != pendingSnapshot.second) {
+ // If the quality is different, re-encode the bitmap.
+ outputStream.reset();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, pendingSnapshot.second, outputStream);
+ jpegBytes = outputStream.toByteArray();
+ jpegQuality = pendingSnapshot.second;
+ }
+ writeJpegBytesToSurface(jpegOutput.getFirst(), requireNonNull(jpegBytes));
+ pendingSnapshot.first.set(null);
+ }
+ mPendingSnapshots.clear();
+ }
+
+ private void failAllPendingSnapshots(@NonNull Throwable throwable) {
+ for (Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot :
+ mPendingSnapshots) {
+ pendingSnapshot.first.setException(throwable);
}
mPendingSnapshots.clear();
}
@NonNull
- private byte[] getJpegByteArray(@NonNull Size size, @NonNull float[] textureTransform) {
+ private Bitmap getBitmap(@NonNull Size size, @NonNull float[] textureTransform) {
// Flip the snapshot. This is for reverting the GL transform added in SurfaceOutputImpl.
float[] snapshotTransform = new float[16];
// TODO(b/278109696): move GL flipping to MatrixExt.
@@ -265,11 +292,8 @@
Matrix.scaleM(snapshotTransform, 0, 1f, -1f, 1f);
Matrix.multiplyMM(snapshotTransform, 0, snapshotTransform, 0, textureTransform, 0);
// Take a snapshot Bitmap and compress it to JPEG.
- Bitmap bitmap = mGlRenderer.snapshot(size, snapshotTransform);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- // TODO: Use the JPEG quality from SessionConfig.
- bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
- return outputStream.toByteArray();
+ return mGlRenderer.snapshot(size, snapshotTransform);
+
}
@WorkerThread
@@ -279,8 +303,9 @@
for (SurfaceOutput surfaceOutput : mOutputSurfaces.keySet()) {
surfaceOutput.close();
}
- for (CallbackToFutureAdapter.Completer<Void> completer : mPendingSnapshots) {
- completer.setException(
+ for (Pair<CallbackToFutureAdapter.Completer<Void>, Integer> pendingSnapshot :
+ mPendingSnapshots) {
+ pendingSnapshot.first.setException(
new Exception("Failed to snapshot: DefaultSurfaceProcessor is released."));
}
mOutputSurfaces.clear();
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java
index 6260709..0dd1f6da 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorInternal.java
@@ -18,6 +18,7 @@
import android.os.Build;
+import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.core.SurfaceProcessor;
@@ -51,7 +52,7 @@
* Takes a snapshot of the next available frame and write it to JPEG outputs.
*/
@NonNull
- default ListenableFuture<Void> snapshot() {
+ default ListenableFuture<Void> snapshot(@IntRange(from = 0, to = 100) int jpegQuality) {
return Futures.immediateFuture(null);
}
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java
index 3873031..853f16c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceProcessorWithExecutor.java
@@ -16,6 +16,7 @@
package androidx.camera.core.processing;
+import static androidx.camera.core.impl.utils.futures.Futures.immediateFailedFuture;
import static androidx.core.util.Preconditions.checkState;
import android.os.Build;
@@ -29,6 +30,8 @@
import androidx.camera.core.SurfaceProcessor;
import androidx.camera.core.SurfaceRequest;
+import com.google.common.util.concurrent.ListenableFuture;
+
import java.util.concurrent.Executor;
/**
@@ -91,6 +94,13 @@
});
}
+ @NonNull
+ @Override
+ public ListenableFuture<Void> snapshot(int jpegQuality) {
+ return immediateFailedFuture(
+ new Exception("Snapshot not supported by external SurfaceProcessor"));
+ }
+
@Override
public void release() {
// No-op. External SurfaceProcessor should not be released by CameraX.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
index 67ab0e2..4ba6851 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
@@ -102,10 +102,10 @@
@NonNull UseCaseConfigFactory useCaseConfigFactory) {
super(DEFAULT_CONFIG);
mVirtualCamera = new VirtualCamera(parentCamera, children, useCaseConfigFactory,
- () -> {
+ jpegQuality -> {
SurfaceProcessorNode sharingNode = mSharingNode;
if (sharingNode != null) {
- return sharingNode.getSurfaceProcessor().snapshot();
+ return sharingNode.getSurfaceProcessor().snapshot(jpegQuality);
} else {
return Futures.immediateFailedFuture(new Exception(
"Failed to take picture: pipeline is not ready."));
@@ -312,7 +312,7 @@
* Takes a snapshot of the current stream and write it to the children with JPEG Surface.
*/
@NonNull
- ListenableFuture<Void> jpegSnapshot();
+ ListenableFuture<Void> jpegSnapshot(int jpegQuality);
}
@VisibleForTesting
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java
index 887e1e5..1ca8ace 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/VirtualCameraControl.java
@@ -18,6 +18,7 @@
import static androidx.core.util.Preconditions.checkArgument;
import static java.util.Collections.singletonList;
+import static java.util.Objects.requireNonNull;
import android.graphics.Rect;
import android.os.Build;
@@ -43,6 +44,8 @@
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class VirtualCameraControl implements CameraControlInternal {
+ private static final int DEFAULT_JPEG_QUALITY = 100;
+
private final CameraControlInternal mParent;
private final StreamSharing.Control mStreamSharingControl;
@@ -121,7 +124,13 @@
@ImageCapture.CaptureMode int captureMode,
@ImageCapture.FlashType int flashType) {
checkArgument(captureConfigs.size() == 1, "Only support one capture config.");
- return Futures.allAsList(singletonList(mStreamSharingControl.jpegSnapshot()));
+ int jpegQuality = getJpegQuality(captureConfigs.get(0));
+ return Futures.allAsList(singletonList(mStreamSharingControl.jpegSnapshot(jpegQuality)));
+ }
+
+ private int getJpegQuality(@NonNull CaptureConfig captureConfig) {
+ return requireNonNull(captureConfig.getImplementationOptions().retrieveOption(
+ CaptureConfig.OPTION_JPEG_QUALITY, DEFAULT_JPEG_QUALITY));
}
@NonNull
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
index a7143fb..5581da2 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
@@ -328,14 +328,14 @@
@Config(minSdk = 28)
@Test
- fun extensionIsOn_pipelineDisabled() {
- assertThat(
- bindImageCapture(
- useProcessingPipeline = true,
- bufferFormat = ImageFormat.JPEG,
- sessionProcessor = FakeSessionProcessor(null, null)
- ).isProcessingPipelineEnabled
- ).isFalse()
+ fun extensionIsOn_pipelineEnabled() {
+ val imageCapture = bindImageCapture(
+ useProcessingPipeline = true,
+ bufferFormat = ImageFormat.JPEG,
+ sessionProcessor = FakeSessionProcessor(null, null)
+ )
+ assertThat(imageCapture.isProcessingPipelineEnabled).isTrue()
+ assertThat(imageCapture.imagePipeline!!.expectsMetadata()).isFalse()
}
@Test
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt
index fee7f3e..d8674dc 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/StreamSpecTest.kt
@@ -20,6 +20,9 @@
import android.util.Range
import android.util.Size
import androidx.camera.core.DynamicRange
+import androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_FORMAT
+import androidx.camera.core.impl.UseCaseConfigFactory.CaptureType
+import androidx.camera.testing.fakes.FakeUseCaseConfig
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -70,8 +73,30 @@
assertThat(streamSpec.expectedFrameRateRange).isEqualTo(TEST_EXPECTED_FRAME_RATE_RANGE)
}
+ @Test
+ fun defaultImplementationOptionsIsNull() {
+ val streamSpec = StreamSpec.builder(TEST_RESOLUTION).build()
+
+ assertThat(streamSpec.implementationOptions)
+ .isNull()
+ }
+
+ @Test
+ fun canRetrieveStreamUseCase() {
+ val streamSpec = StreamSpec.builder(TEST_RESOLUTION)
+ .setImplementationOptions(TEST_IMPLEMENTATION_OPTION)
+ .build()
+
+ assertThat(streamSpec.implementationOptions!!.containsOption(OPTION_INPUT_FORMAT)).isTrue()
+ assertThat(streamSpec.implementationOptions!!.retrieveOption(OPTION_INPUT_FORMAT))
+ .isEqualTo(TEST_INPUT_FORMAT)
+ }
+
companion object {
private val TEST_RESOLUTION = Size(640, 480)
private val TEST_EXPECTED_FRAME_RATE_RANGE = Range(30, 30)
+ private const val TEST_INPUT_FORMAT = 1
+ private val TEST_IMPLEMENTATION_OPTION =
+ FakeUseCaseConfig.Builder(CaptureType.PREVIEW, TEST_INPUT_FORMAT).useCaseConfig.config
}
}
\ No newline at end of file
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
index 9f8be2f..571a6b7 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
@@ -24,6 +24,7 @@
import androidx.camera.core.CameraEffect.PREVIEW
import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
import androidx.camera.core.ImageCapture
+import androidx.camera.core.ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY
import androidx.camera.core.ImageProxy
import androidx.camera.core.impl.CameraCaptureCallback
import androidx.camera.core.impl.CameraCaptureResult
@@ -99,9 +100,10 @@
}
@Test
- fun childTakingPicture_triggersSnapshot() {
- // Arrange: set up StreamSharing with ImageCapture as child
- val imageCapture = ImageCapture.Builder().build()
+ fun childTakingPicture_getJpegQuality() {
+ // Arrange: set up StreamSharing with min latency ImageCapture as child
+ val imageCapture =
+ ImageCapture.Builder().setCaptureMode(CAPTURE_MODE_MINIMIZE_LATENCY).build()
streamSharing = StreamSharing(camera, setOf(child1, imageCapture), useCaseConfigFactory)
streamSharing.bindToCamera(camera, null, defaultConfig)
streamSharing.onSuggestedStreamSpecUpdated(StreamSpec.builder(size).build())
@@ -112,8 +114,8 @@
})
shadowOf(getMainLooper()).idle()
- // Assert: the snapshot is triggered.
- assertThat(sharingProcessor.isSnapshotTriggered).isTrue()
+ // Assert: the jpeg quality of min latency capture is 95.
+ assertThat(sharingProcessor.jpegQuality).isEqualTo(95)
}
@Test
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
index 46e04fa..78fa363 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/internal/sessionprocessor/BasicExtenderSessionProcessorTest.kt
@@ -265,7 +265,7 @@
analysisSemaphore
)
- fakeLifecycleOwner.pauseAndStop()
+ withContext(Dispatchers.Main) { fakeLifecycleOwner.pauseAndStop() }
delay(1000)
previewSemaphore.drainPermits()
@@ -308,24 +308,28 @@
})
}
- fakeLifecycleOwner.pauseAndStop()
+ withContext(Dispatchers.Main) { fakeLifecycleOwner.pauseAndStop() }
assertThat(cameraClosedLatch.await(1, TimeUnit.SECONDS)).isTrue()
- fakeCaptureExtenderImpl.assertInvokeOrder(listOf(
- "onInit",
- "onPresetSession",
- "onEnableSession",
- "onDisableSession",
- "onDeInit",
- ))
+ fakeCaptureExtenderImpl.assertInvokeOrder(
+ listOf(
+ "onInit",
+ "onPresetSession",
+ "onEnableSession",
+ "onDisableSession",
+ "onDeInit",
+ )
+ )
- fakePreviewExtenderImpl.assertInvokeOrder(listOf(
- "onInit",
- "onPresetSession",
- "onEnableSession",
- "onDisableSession",
- "onDeInit",
- ))
+ fakePreviewExtenderImpl.assertInvokeOrder(
+ listOf(
+ "onInit",
+ "onPresetSession",
+ "onEnableSession",
+ "onDisableSession",
+ "onDeInit",
+ )
+ )
}
class ResultMonitor {
@@ -342,6 +346,7 @@
}
}
}
+
fun assertCaptureKey(key: CaptureRequest.Key<*>, value: Any) {
keyToCheck = key
valueToCheck = value
@@ -370,9 +375,11 @@
val previewSemaphore = Semaphore(0)
val analysisSemaphore = Semaphore(0)
fakePreviewExtenderImpl.captureStage = createCaptureStage(
- parameters = listOf(Pair(
- CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF
- ))
+ parameters = listOf(
+ Pair(
+ CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF
+ )
+ )
)
verifyUseCasesOutput(
@@ -420,8 +427,11 @@
// Trigger RequestUpdateProcessor to update repeating request to have new parameters.
fakePreviewExtenderImpl.fakeRequestUpdateProcessor?.captureStage =
createCaptureStage(
- parameters = listOf(Pair(CaptureRequest.CONTROL_AE_MODE,
- CaptureRequest.CONTROL_AE_MODE_OFF)
+ parameters = listOf(
+ Pair(
+ CaptureRequest.CONTROL_AE_MODE,
+ CaptureRequest.CONTROL_AE_MODE_OFF
+ )
)
)
@@ -724,6 +734,7 @@
fun assertInvokeOrder(expectList: List<String>) {
assertThat(expectList).containsExactlyElementsIn(invokeList).inOrder()
}
+
override fun onInit(
cameraId: String,
cameraCharacteristics: CameraCharacteristics,
@@ -735,14 +746,17 @@
override fun onDeInit() {
recordInvoking("onDeInit")
}
+
override fun onPresetSession(): CaptureStageImpl? {
recordInvoking("onPresetSession")
return null
}
+
override fun onEnableSession(): CaptureStageImpl? {
recordInvoking("onEnableSession")
return onEnableSessionCaptureStage
}
+
override fun onDisableSession(): CaptureStageImpl? {
recordInvoking("onDisableSession")
return onDisableSessionCaptureStage
@@ -762,17 +776,21 @@
when (processorType) {
PROCESSOR_TYPE_REQUEST_UPDATE_ONLY ->
fakeRequestUpdateProcessor = FakeRequestUpdateProcessor()
+
PROCESSOR_TYPE_IMAGE_PROCESSOR ->
fakePreviewImageProcessorImpl = FakePreviewImageProcessorImpl()
+
PROCESSOR_TYPE_NONE -> {}
}
}
+
override fun isExtensionAvailable(
cameraId: String,
cameraCharacteristics: CameraCharacteristics
): Boolean {
return true
}
+
override fun init(cameraId: String, cameraCharacteristics: CameraCharacteristics) {
recordInvoking("init")
}
@@ -795,6 +813,7 @@
fun setCaptureStage(captureStage: CaptureStageImpl) {
_captureStage = captureStage
}
+
override fun getProcessorType() = processorType
override fun getProcessor() =
when (processorType) {
@@ -832,6 +851,7 @@
override fun init(cameraId: String, cameraCharacteristics: CameraCharacteristics) {
recordInvoking("init")
}
+
override fun getCaptureProcessor() = fakeCaptureProcessorImpl
override fun getCaptureStages() = _captureStages
@@ -959,6 +979,7 @@
deferredSubmit = CompletableDeferred<List<RequestProcessor.Request>>()
}
}
+
override fun submit(
request: RequestProcessor.Request,
callback: RequestProcessor.Callback
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreAudioProblematicDeviceRule.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreAudioProblematicDeviceRule.kt
new file mode 100644
index 0000000..1d1713e
--- /dev/null
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreAudioProblematicDeviceRule.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.testing
+
+import androidx.annotation.RequiresApi
+import androidx.camera.testing.IgnoreProblematicDeviceRule.Companion.isPixel2Api26Emulator
+import org.junit.AssumptionViolatedException
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * Test class to set the TestRule that should not be run on the audio problematically devices.
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class IgnoreAudioProblematicDeviceRule : TestRule {
+ private val isProblematicDevices = isPixel2Api26Emulator
+
+ override fun apply(base: Statement, description: Description): Statement {
+ return object : Statement() {
+ override fun evaluate() {
+ if (isProblematicDevices) {
+ throw AssumptionViolatedException(
+ "AudioRecord of the emulator may not be well prepared for related" +
+ " tests. Ignore the test: " + description.displayName +
+ ". To test on emulator devices, please remove the" +
+ " IgnoreAudioProblematicallyDeviceRule from the test class."
+ )
+ } else {
+ base.evaluate()
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt
index 73fee52..99214e5 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/IgnoreProblematicDeviceRule.kt
@@ -30,23 +30,9 @@
*/
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class IgnoreProblematicDeviceRule : TestRule {
- private var avdName: String = try {
- val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- device.executeShellCommand("getprop ro.kernel.qemu.avd_name").filterNot {
- it == '_' || it == '-' || it == ' '
- }
- } catch (e: Exception) {
- Log.d("ProblematicDeviceRule", "Cannot get avd name", e)
- ""
- }
-
- private val pixel2Api26Emulator = isEmulator && avdName.contains(
- "Pixel2", ignoreCase = true
- ) && Build.VERSION.SDK_INT == Build.VERSION_CODES.O
-
private val api21Emulator = isEmulator && Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
- private val isProblematicDevices = pixel2Api26Emulator || api21Emulator
+ private val isProblematicDevices = isPixel2Api26Emulator || api21Emulator
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
@@ -75,7 +61,19 @@
EMULATOR_HARDWARE_RANCHU,
EMULATOR_HARDWARE_GCE
)
+ private var avdName: String = try {
+ val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ device.executeShellCommand("getprop ro.kernel.qemu.avd_name").filterNot {
+ it == '_' || it == '-' || it == ' '
+ }
+ } catch (e: Exception) {
+ Log.d("ProblematicDeviceRule", "Cannot get avd name", e)
+ ""
+ }
val isEmulator = emulatorHardwareNames.contains(Build.HARDWARE.lowercase())
+ val isPixel2Api26Emulator = isEmulator && avdName.contains(
+ "Pixel2", ignoreCase = true
+ ) && Build.VERSION.SDK_INT == Build.VERSION_CODES.O
}
}
\ No newline at end of file
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java
index 269b142a..94bd4cc 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeSurfaceProcessorInternal.java
@@ -18,6 +18,7 @@
import android.os.Build;
+import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.core.impl.utils.futures.Futures;
@@ -35,7 +36,7 @@
SurfaceProcessorInternal {
private boolean mIsReleased;
- private boolean mIsSnapshotTriggered = false;
+ private int mJpegQuality = 0;
/**
* {@inheritDoc}
@@ -64,12 +65,13 @@
@Override
@NonNull
- public ListenableFuture<Void> snapshot() {
- mIsSnapshotTriggered = true;
+ public ListenableFuture<Void> snapshot(int jpegQuality) {
+ mJpegQuality = jpegQuality;
return Futures.immediateFuture(null);
}
- public boolean isSnapshotTriggered() {
- return mIsSnapshotTriggered;
+ @IntRange(from = 0, to = 100)
+ public int getJpegQuality() {
+ return mJpegQuality;
}
}
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt
index 39cbed2..4424a86 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/config/AudioSettingsAudioProfileResolverTest.kt
@@ -30,6 +30,7 @@
import androidx.camera.testing.CameraPipeConfigTestRule
import androidx.camera.testing.CameraUtil
import androidx.camera.testing.CameraXUtil
+import androidx.camera.testing.IgnoreAudioProblematicDeviceRule
import androidx.camera.video.AudioSpec
import androidx.camera.video.Quality
import androidx.camera.video.Recorder
@@ -64,6 +65,10 @@
private val cameraConfig: CameraXConfig
) {
+ // Ignore problematic device for b/277176784
+ @get:Rule
+ val ignoreProblematicDeviceRule = IgnoreAudioProblematicDeviceRule()
+
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{0}")
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt
index bf7c596..9f85c6c 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/internal/encoder/AudioEncoderTest.kt
@@ -16,6 +16,7 @@
package androidx.camera.video.internal.encoder
import android.media.MediaCodecInfo
+import android.os.Build
import androidx.camera.core.impl.Observable.Observer
import androidx.camera.core.impl.Timebase
import androidx.camera.core.impl.utils.executor.CameraXExecutors
@@ -40,6 +41,7 @@
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.junit.After
+import org.junit.Assume.assumeFalse
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -128,6 +130,12 @@
@Test
fun canRestartEncoder() {
+ // Skip for b/269129619
+ assumeFalse(
+ "Skip test for Cuttlefish API 30 flaky native crash",
+ Build.MODEL.contains("Cuttlefish") && Build.VERSION.SDK_INT == 30
+ )
+
// Arrange.
fakeAudioLoop.start()
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt
index b4a58eb..0add8e7 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageAnalysisBaseTest.kt
@@ -33,6 +33,9 @@
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertWithMessage
import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
import org.junit.Assume
import org.junit.BeforeClass
import org.junit.Rule
@@ -87,10 +90,12 @@
CoreAppTestUtil.prepareDeviceUI(InstrumentationRegistry.getInstrumentation())
}
- protected fun tearDown() {
- val context = ApplicationProvider.getApplicationContext<Context>()
- val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
- cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+ protected fun tearDown(): Unit = runBlocking {
+ withContext(Dispatchers.Main) {
+ val context = ApplicationProvider.getApplicationContext<Context>()
+ val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
+ cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+ }
mDevice.unfreezeRotation()
}
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt
index 29ae33f..741b76f 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureBaseTest.kt
@@ -38,6 +38,9 @@
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeTrue
import org.junit.BeforeClass
@@ -109,10 +112,12 @@
assumeTrue("Failed to create pictures directory", createPicturesFolder())
}
- protected fun tearDown() {
- val context = ApplicationProvider.getApplicationContext<Context>()
- val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
- cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+ protected fun tearDown(): Unit = runBlocking {
+ withContext(Dispatchers.Main) {
+ val context = ApplicationProvider.getApplicationContext<Context>()
+ val cameraProvider = ProcessCameraProvider.getInstance(context)[10, TimeUnit.SECONDS]
+ cameraProvider.shutdown()[10, TimeUnit.SECONDS]
+ }
mDevice.unfreezeRotation()
}
diff --git a/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml b/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml
index d88bd0d..e2ec81f 100644
--- a/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml
+++ b/car/app/app-samples/navigation/mobile/src/main/AndroidManifestWithSdkVersion.xml
@@ -37,31 +37,18 @@
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
- <!-- Various required feature settings for an automotive app. -->
- <uses-feature
- android:name="android.hardware.type.automotive"
- android:required="true" />
- <uses-feature
- android:name="android.software.car.templates_host"
- android:required="true" />
- <uses-feature
- android:name="android.hardware.wifi"
- android:required="false" />
- <uses-feature
- android:name="android.hardware.screen.portrait"
- android:required="false" />
- <uses-feature
- android:name="android.hardware.screen.landscape"
- android:required="false" />
+ <!-- For Microphone Recording -->
+ <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
- <meta-data
- android:name="com.android.automotive"
- android:resource="@xml/automotive_app_desc"
- tools:ignore="MetadataTagInsideApplicationTag" />
+ <meta-data
+ android:name="com.google.android.gms.car.application"
+ android:resource="@xml/automotive_app_desc"
+ tools:ignore="MetadataTagInsideApplicationTag" />
<meta-data android:name="androidx.car.app.minCarApiLevel"
android:value="1"
@@ -77,31 +64,16 @@
<category android:name="androidx.car.app.category.NAVIGATION"/>
<category android:name="androidx.car.app.category.FEATURE_CLUSTER"/>
</intent-filter>
+ <intent-filter>
+ <action android:name="androidx.car.app.action.NAVIGATE" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ <data android:scheme="geo" />
+ </intent-filter>
</service>
<service
android:name="androidx.car.app.sample.navigation.common.nav.NavigationService"
android:enabled="true"
android:exported="true">
</service>
-
- <activity
- android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
- android:name="androidx.car.app.activity.CarAppActivity"
- android:exported="true"
- android:launchMode="singleTask"
- android:label="Navigation">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- <intent-filter>
- <action android:name="androidx.car.app.action.NAVIGATE" />
- <category android:name="android.intent.category.DEFAULT"/>
- <data android:scheme="geo" />
- </intent-filter>
- <meta-data android:name="distractionOptimized" android:value="true"/>
- </activity>
-
</application>
</manifest>
diff --git a/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml b/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml
index e614136..3d44975 100644
--- a/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml
+++ b/car/app/app-samples/showcase/automotive/src/main/AndroidManifestWithSdkVersion.xml
@@ -27,7 +27,7 @@
<uses-sdk
android:minSdkVersion="29"
- android:targetSdkVersion="29" />
+ android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
diff --git a/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml b/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml
index 25e08d7..1c9c267 100644
--- a/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml
+++ b/car/app/app-samples/showcase/mobile/src/main/AndroidManifestWithSdkVersion.xml
@@ -27,7 +27,7 @@
<uses-sdk
android:minSdkVersion="23"
- android:targetSdkVersion="29" />
+ android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index 1f0f4cf..c8ce9a4 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -225,6 +225,7 @@
@androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
method public int getContentLimit(int);
+ method @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
@@ -987,8 +988,10 @@
}
@androidx.car.app.annotations.CarProtocol public final class Row implements androidx.car.app.model.Item {
+ method @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
method public androidx.car.app.model.CarIcon? getImage();
method public androidx.car.app.model.Metadata? getMetadata();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
method public androidx.car.app.model.OnClickDelegate? getOnClickDelegate();
method public int getRowImageType();
method public java.util.List<androidx.car.app.model.CarText!> getTexts();
@@ -1006,6 +1009,7 @@
public static final class Row.Builder {
ctor public Row.Builder();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
method public androidx.car.app.model.Row.Builder addText(CharSequence);
method public androidx.car.app.model.Row.Builder addText(androidx.car.app.model.CarText);
method public androidx.car.app.model.Row build();
@@ -1014,6 +1018,7 @@
method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon);
method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon, int);
method public androidx.car.app.model.Row.Builder setMetadata(androidx.car.app.model.Metadata);
+ method @IntRange(from=0) @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
method public androidx.car.app.model.Row.Builder setOnClickListener(androidx.car.app.model.OnClickListener);
method public androidx.car.app.model.Row.Builder setTitle(CharSequence);
method public androidx.car.app.model.Row.Builder setTitle(androidx.car.app.model.CarText);
diff --git a/car/app/app/api/public_plus_experimental_current.txt b/car/app/app/api/public_plus_experimental_current.txt
index 33ffc83..02f26c1 100644
--- a/car/app/app/api/public_plus_experimental_current.txt
+++ b/car/app/app/api/public_plus_experimental_current.txt
@@ -233,7 +233,7 @@
@androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
method public int getContentLimit(int);
- method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
@@ -1449,10 +1449,10 @@
}
@androidx.car.app.annotations.CarProtocol public final class Row implements androidx.car.app.model.Item {
- method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
method public androidx.car.app.model.CarIcon? getImage();
method public androidx.car.app.model.Metadata? getMetadata();
- method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
method public androidx.car.app.model.OnClickDelegate? getOnClickDelegate();
method public int getRowImageType();
method public java.util.List<androidx.car.app.model.CarText!> getTexts();
@@ -1470,7 +1470,7 @@
public static final class Row.Builder {
ctor public Row.Builder();
- method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
+ method @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
method public androidx.car.app.model.Row.Builder addText(CharSequence);
method public androidx.car.app.model.Row.Builder addText(androidx.car.app.model.CarText);
method public androidx.car.app.model.Row build();
@@ -1479,7 +1479,7 @@
method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon);
method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon, int);
method public androidx.car.app.model.Row.Builder setMetadata(androidx.car.app.model.Metadata);
- method @IntRange(from=0) @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
+ method @IntRange(from=0) @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
method public androidx.car.app.model.Row.Builder setOnClickListener(androidx.car.app.model.OnClickListener);
method public androidx.car.app.model.Row.Builder setTitle(CharSequence);
method public androidx.car.app.model.Row.Builder setTitle(androidx.car.app.model.CarText);
@@ -1529,14 +1529,12 @@
method public String getContentId();
method public androidx.car.app.model.CarIcon getIcon();
method public androidx.car.app.model.CarText getTitle();
- method @Deprecated public boolean isActive();
- method public androidx.car.app.model.Tab.Builder toBuilder();
}
public static final class Tab.Builder {
ctor public Tab.Builder();
+ ctor public Tab.Builder(androidx.car.app.model.Tab);
method public androidx.car.app.model.Tab build();
- method @Deprecated public androidx.car.app.model.Tab.Builder setActive(boolean);
method public androidx.car.app.model.Tab.Builder setContentId(String);
method public androidx.car.app.model.Tab.Builder setIcon(androidx.car.app.model.CarIcon);
method public androidx.car.app.model.Tab.Builder setTitle(CharSequence);
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index 1f0f4cf..c8ce9a4 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -225,6 +225,7 @@
@androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
method public int getContentLimit(int);
+ method @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
@@ -987,8 +988,10 @@
}
@androidx.car.app.annotations.CarProtocol public final class Row implements androidx.car.app.model.Item {
+ method @androidx.car.app.annotations.RequiresCarApi(6) public java.util.List<androidx.car.app.model.Action!> getActions();
method public androidx.car.app.model.CarIcon? getImage();
method public androidx.car.app.model.Metadata? getMetadata();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public int getNumericDecoration();
method public androidx.car.app.model.OnClickDelegate? getOnClickDelegate();
method public int getRowImageType();
method public java.util.List<androidx.car.app.model.CarText!> getTexts();
@@ -1006,6 +1009,7 @@
public static final class Row.Builder {
ctor public Row.Builder();
+ method @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder addAction(androidx.car.app.model.Action);
method public androidx.car.app.model.Row.Builder addText(CharSequence);
method public androidx.car.app.model.Row.Builder addText(androidx.car.app.model.CarText);
method public androidx.car.app.model.Row build();
@@ -1014,6 +1018,7 @@
method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon);
method public androidx.car.app.model.Row.Builder setImage(androidx.car.app.model.CarIcon, int);
method public androidx.car.app.model.Row.Builder setMetadata(androidx.car.app.model.Metadata);
+ method @IntRange(from=0) @androidx.car.app.annotations.RequiresCarApi(6) public androidx.car.app.model.Row.Builder setNumericDecoration(int);
method public androidx.car.app.model.Row.Builder setOnClickListener(androidx.car.app.model.OnClickListener);
method public androidx.car.app.model.Row.Builder setTitle(CharSequence);
method public androidx.car.app.model.Row.Builder setTitle(androidx.car.app.model.CarText);
diff --git a/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java b/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
index c8fcccd..e9e8817 100644
--- a/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
+++ b/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
@@ -31,7 +31,6 @@
import androidx.car.app.HostDispatcher;
import androidx.car.app.HostException;
import androidx.car.app.R;
-import androidx.car.app.annotations.ExperimentalCarApi;
import androidx.car.app.annotations.RequiresCarApi;
import androidx.car.app.managers.Manager;
import androidx.car.app.utils.LogTags;
@@ -149,7 +148,6 @@
*
*/
@RequiresCarApi(6)
- @ExperimentalCarApi
public boolean isAppDrivenRefreshEnabled() {
Boolean result;
try {
diff --git a/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java b/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
index 8614a79..034b5de 100644
--- a/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
+++ b/car/app/app/src/main/java/androidx/car/app/messaging/model/CarMessage.java
@@ -16,6 +16,8 @@
package androidx.car.app.messaging.model;
+import static androidx.car.app.messaging.model.ConversationItem.validateSender;
+
import static java.util.Objects.requireNonNull;
import android.os.Bundle;
@@ -72,7 +74,7 @@
}
CarMessage(@NonNull Builder builder) {
- this.mSender = builder.mSender == null ? null : requireNonNull(builder.mSender).toBundle();
+ this.mSender = builder.mSender == null ? null : validateSender(builder.mSender).toBundle();
this.mBody = requireNonNull(builder.mBody);
this.mReceivedTimeEpochMillis = builder.mReceivedTimeEpochMillis;
this.mIsRead = builder.mIsRead;
@@ -123,7 +125,13 @@
long mReceivedTimeEpochMillis;
boolean mIsRead;
- /** Sets a {@link Person} representing the message sender */
+ /**
+ * Sets a {@link Person} representing the message sender
+ *
+ * <p> The {@link Person} must specify a non-null
+ * {@link Person.Builder#setName(CharSequence)} and
+ * {@link Person.Builder#setKey(String)}.
+ */
public @NonNull Builder setSender(@Nullable Person sender) {
mSender = sender;
return this;
diff --git a/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java b/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
index 5956a59..b63b93e 100644
--- a/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
+++ b/car/app/app/src/main/java/androidx/car/app/messaging/model/ConversationItem.java
@@ -95,7 +95,7 @@
ConversationItem(@NonNull Builder builder) {
this.mId = requireNonNull(builder.mId);
this.mTitle = requireNonNull(builder.mTitle);
- this.mSelf = requireNonNull(builder.mSelf).toBundle();
+ this.mSelf = validateSender(builder.mSelf).toBundle();
this.mIcon = builder.mIcon;
this.mIsGroupConversation = builder.mIsGroupConversation;
this.mMessages = requireNonNull(CollectionUtils.unmodifiableCopy(builder.mMessages));
@@ -175,6 +175,19 @@
return mConversationCallbackDelegate;
}
+ /**
+ * Verifies that a given {@link Person} has the required fields to be a message sender. Returns
+ * the input {@link Person} if valid, or throws an exception if invalid.
+ *
+ * <p> See also {@link ConversationItem#getSelf()} and {@link CarMessage#getSender()}.
+ */
+ static Person validateSender(@Nullable Person person) {
+ requireNonNull(person);
+ requireNonNull(person.getName());
+ requireNonNull(person.getKey());
+ return person;
+ }
+
/** A builder for {@link ConversationItem} */
public static final class Builder {
@Nullable
@@ -221,7 +234,13 @@
return this;
}
- /** Sets a {@link Person} for the conversation */
+ /**
+ * Sets a {@link Person} for the conversation
+ *
+ * <p> The {@link Person} must specify a non-null
+ * {@link Person.Builder#setName(CharSequence)} and
+ * {@link Person.Builder#setKey(String)}.
+ */
@NonNull
public Builder setSelf(@NonNull Person self) {
mSelf = self;
diff --git a/car/app/app/src/main/java/androidx/car/app/model/Row.java b/car/app/app/src/main/java/androidx/car/app/model/Row.java
index 9cee293..857da8b 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/Row.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/Row.java
@@ -30,12 +30,11 @@
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.car.app.annotations.CarProtocol;
-import androidx.car.app.annotations.ExperimentalCarApi;
+import androidx.car.app.annotations.KeepFields;
import androidx.car.app.annotations.RequiresCarApi;
import androidx.car.app.model.constraints.ActionsConstraints;
import androidx.car.app.model.constraints.CarIconConstraints;
import androidx.car.app.model.constraints.CarTextConstraints;
-import androidx.car.app.annotations.KeepFields;
import androidx.car.app.utils.CollectionUtils;
import java.lang.annotation.Retention;
@@ -155,7 +154,6 @@
*
* @see Builder#addAction(Action)
*/
- @ExperimentalCarApi
@NonNull
@RequiresCarApi(6)
public List<Action> getActions() {
@@ -173,11 +171,12 @@
*
* <p> Numeric decorations are displayed at the end of the row, but before any actions.
*
+ * <p> Numeric decorations are only allowed in full-width lists.
+ *
* <p> {@link Row#NO_DECORATION} will be returned if the row does not contain a decoration.
*
* @see Builder#setNumericDecoration(int)
*/
- @ExperimentalCarApi
@RequiresCarApi(6)
public int getNumericDecoration() {
return mNumericDecoration;
@@ -524,8 +523,7 @@
}
/**
- * Adds an additional action to the end of the row. Actions are not displayed in
- * half-list templates.
+ * Adds an additional action to the end of the row.
*
* @throws NullPointerException if {@code action} is {@code null}
* @throws IllegalArgumentException if {@code action} contains unsupported Action types,
@@ -533,7 +531,6 @@
* not contain a valid {@link CarIcon}.
*/
//TODO(b/260557014): Update docs when half-list UX is defined
- @ExperimentalCarApi
@NonNull
@RequiresCarApi(6)
public Builder addAction(@NonNull Action action) {
@@ -559,7 +556,6 @@
* @throws IllegalArgumentException if {@code decoration} is invalid
*/
//TODO(b/260557014): Update docs when half-list UX is defined
- @ExperimentalCarApi
@NonNull
@RequiresCarApi(6)
@IntRange(from = 0)
@@ -699,4 +695,4 @@
public Builder() {
}
}
-}
+}
\ No newline at end of file
diff --git a/car/app/app/src/main/java/androidx/car/app/model/Tab.java b/car/app/app/src/main/java/androidx/car/app/model/Tab.java
index b6f6089..d99fd60 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/Tab.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/Tab.java
@@ -41,7 +41,6 @@
/** Content ID for an empty Tab object. */
private static final String EMPTY_TAB_CONTENT_ID = "EMPTY_TAB_CONTENT_ID";
- private final boolean mIsActive;
@Nullable
private final CarText mTitle;
@Nullable
@@ -80,17 +79,6 @@
return requireNonNull(mIcon);
}
- /**
- * Indicates if this is the currently active tab.
- *
- * @see Tab.Builder#setActive(boolean)
- * @deprecated use {@link TabTemplate#getActiveTabContentId()} instead.
- */
- @Deprecated
- public boolean isActive() {
- return mIsActive;
- }
-
@Override
@NonNull
public String toString() {
@@ -100,8 +88,6 @@
+ mContentId
+ ", icon: "
+ mIcon
- + ", isActive "
- + mIsActive
+ "]";
}
@@ -110,8 +96,7 @@
return Objects.hash(
mTitle,
mContentId,
- mIcon,
- mIsActive);
+ mIcon);
}
@Override
@@ -126,22 +111,12 @@
return Objects.equals(mTitle, otherTab.mTitle)
&& Objects.equals(mContentId, otherTab.mContentId)
- && Objects.equals(mIcon, otherTab.mIcon)
- && mIsActive == otherTab.isActive();
- }
-
- /**
- * Creates and returns a new {@link Builder} initialized with this {@link Tab}'s data.
- */
- @NonNull
- public Tab.Builder toBuilder() {
- return new Tab.Builder(this);
+ && Objects.equals(mIcon, otherTab.mIcon);
}
Tab(Tab.Builder builder) {
mTitle = builder.mTitle;
mIcon = builder.mIcon;
- mIsActive = builder.mIsActive;
if (builder.mContentId != null) {
mContentId = builder.mContentId;
@@ -155,13 +130,10 @@
mTitle = null;
mContentId = EMPTY_TAB_CONTENT_ID;
mIcon = null;
- mIsActive = false;
}
/** A builder of {@link Tab}. */
public static final class Builder {
- boolean mIsActive;
-
@Nullable
CarText mTitle;
@@ -194,6 +166,9 @@
/**
* Sets the content ID of the tab.
+ *
+ * @throws NullPointerException if {@code contentId} is {@code null}
+ * @throws IllegalArgumentException if {@code contentId} is empty
*/
@NonNull
public Tab.Builder setContentId(@NonNull String contentId) {
@@ -227,18 +202,6 @@
}
/**
- * Sets the active state of the tab.
- *
- * @deprecated use {@link TabTemplate.Builder#setActiveTabContentId(String)} instead.
- */
- @NonNull
- @Deprecated
- public Tab.Builder setActive(boolean isActive) {
- mIsActive = isActive;
- return this;
- }
-
- /**
* Constructs the {@link Tab} defined by this builder.
*
* @throws IllegalStateException if the tab's title, icon or content ID is not set.
@@ -266,9 +229,8 @@
}
/** Creates a new {@link Builder}, populated from the input {@link Tab} */
- Builder(@NonNull Tab tab) {
+ public Builder(@NonNull Tab tab) {
requireNonNull(tab);
- mIsActive = tab.isActive();
mContentId = tab.getContentId();
mIcon = tab.getIcon();
mTitle = tab.getTitle();
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java
index a7a2fb2..06caf6b 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/CarMessageTest.java
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertThrows;
import androidx.car.app.model.CarText;
-import androidx.core.app.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -60,6 +59,28 @@
);
}
+ public void build_throwsException_ifSenderNameMissing() {
+ assertThrows(
+ NullPointerException.class,
+ () -> TestConversationFactory.createMinimalMessageBuilder()
+ .setSender(TestConversationFactory.createMinimalMessageSenderBuilder()
+ .setName(null)
+ .build())
+ .build()
+ );
+ }
+
+ public void build_throwsException_ifSenderKeyMissing() {
+ assertThrows(
+ NullPointerException.class,
+ () -> TestConversationFactory.createMinimalMessageBuilder()
+ .setSender(TestConversationFactory.createMinimalMessageSenderBuilder()
+ .setKey(null)
+ .build())
+ .build()
+ );
+ }
+
// region .equals() & .hashCode()
@Test
public void equalsAndHashCode_areEqual_forMinimalMessage() {
@@ -93,7 +114,7 @@
.createFullyPopulatedMessageBuilder()
.setSender(
TestConversationFactory
- .createMinimalPersonBuilder()
+ .createMinimalMessageSenderBuilder()
.setKey("Modified Key")
.build()
)
@@ -124,57 +145,6 @@
assertNotEqual(fullyPopulatedMessage, modifiedIsRead);
}
- @Test
- public void equalsAndHashCode_produceCorrectResult_ifSenderIdMissing() {
- Person.Builder senderWithoutId = TestConversationFactory
- .createMinimalPersonBuilder()
- .setKey(null);
- Person.Builder senderWithId = TestConversationFactory
- .createMinimalPersonBuilder()
- .setKey("Test Sender Key");
-
- // Create Test Data
- CarMessage senderKeyMissingWithStandardData =
- TestConversationFactory.createMinimalMessageBuilder()
- .setSender(senderWithoutId.build())
- .build();
- CarMessage senderKeyMissingWithStandardData2 =
- TestConversationFactory.createMinimalMessageBuilder()
- .setSender(senderWithoutId.build())
- .build();
- CarMessage senderKeyMissingWithModifiedData =
- TestConversationFactory.createMinimalMessageBuilder()
- .setSender(senderWithoutId.build())
- .setBody(CarText.create("Modified Message Body"))
- .build();
- CarMessage senderKeyProvidedWithStandardData =
- TestConversationFactory.createMinimalMessageBuilder()
- .setSender(senderWithId.build())
- .build();
- CarMessage senderKeyProvidedWithStandardData2 =
- TestConversationFactory.createMinimalMessageBuilder()
- .setSender(senderWithId.build())
- .build();
- CarMessage senderKeyProvidedWithModifiedData =
- TestConversationFactory.createMinimalMessageBuilder()
- .setSender(senderWithId.build())
- .setBody(CarText.create("Modified Message Body"))
- .build();
-
- // Verify (in)equality
-
- // Sender & message content are equal: == EQUAL ==
- assertEqual(senderKeyMissingWithStandardData, senderKeyMissingWithStandardData2);
- assertEqual(senderKeyProvidedWithStandardData, senderKeyProvidedWithStandardData2);
-
- // One sender is missing a key: == NOT EQUAL ==
- assertNotEqual(senderKeyMissingWithStandardData, senderKeyProvidedWithStandardData);
-
- // Sender is equal, but message content is not: == NOT EQUAL ==
- assertNotEqual(senderKeyMissingWithStandardData, senderKeyMissingWithModifiedData);
- assertNotEqual(senderKeyProvidedWithStandardData, senderKeyProvidedWithModifiedData);
- }
-
private void assertEqual(CarMessage message1, CarMessage message2) {
assertThat(message1).isEqualTo(message2);
assertThat(message1.hashCode()).isEqualTo(message2.hashCode());
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
index 2090047..97cea42 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/ConversationItemTest.java
@@ -62,6 +62,28 @@
);
}
+ public void build_throwsException_ifSenderNameMissing() {
+ assertThrows(
+ NullPointerException.class,
+ () -> TestConversationFactory.createMinimalConversationItemBuilder()
+ .setSelf(TestConversationFactory.createMinimalMessageSenderBuilder()
+ .setName(null)
+ .build())
+ .build()
+ );
+ }
+
+ public void build_throwsException_ifSenderKeyMissing() {
+ assertThrows(
+ NullPointerException.class,
+ () -> TestConversationFactory.createMinimalConversationItemBuilder()
+ .setSelf(TestConversationFactory.createMinimalMessageSenderBuilder()
+ .setKey(null)
+ .build())
+ .build()
+ );
+ }
+
// region .equals() & .hashCode()
@Test
public void equalsAndHashCode_areEqual_forMinimalConversationItem() {
@@ -131,7 +153,8 @@
ConversationItem modifiedConversationCallback =
TestConversationFactory
.createFullyPopulatedConversationItemBuilder()
- .setSelf(TestConversationFactory.createMinimalPersonBuilder().build())
+ .setSelf(
+ TestConversationFactory.createMinimalMessageSenderBuilder().build())
.setConversationCallback(new ConversationCallback() {
@Override
public void onMarkAsRead() {
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java
index 13b4d4f..eb3791c 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/PersonsEqualityHelperTest.java
@@ -34,10 +34,8 @@
@Test
public void equalsAndHashCode_minimalPersons_areEqual() {
- Person person1 =
- TestConversationFactory.createMinimalPersonBuilder().build();
- Person person2 =
- TestConversationFactory.createMinimalPersonBuilder().build();
+ Person person1 = createMinimalPerson();
+ Person person2 = createMinimalPerson();
assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isTrue();
assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isEqualTo(
@@ -53,10 +51,8 @@
@Test
public void equalsAndHashCode_differentName_areNotEqual() {
- Person person1 =
- TestConversationFactory.createMinimalPersonBuilder().setName("Person1").build();
- Person person2 =
- TestConversationFactory.createMinimalPersonBuilder().setName("Person2").build();
+ Person person1 = createMinimalPersonBuilder().setName("Person1").build();
+ Person person2 = createMinimalPersonBuilder().setName("Person2").build();
assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
@@ -65,10 +61,8 @@
@Test
public void equalsAndHashCode_differentKey_areNotEqual() {
- Person person1 =
- TestConversationFactory.createMinimalPersonBuilder().setKey("Person1").build();
- Person person2 =
- TestConversationFactory.createMinimalPersonBuilder().setKey("Person2").build();
+ Person person1 = createMinimalPersonBuilder().setKey("Person1").build();
+ Person person2 = createMinimalPersonBuilder().setKey("Person2").build();
assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
@@ -81,11 +75,9 @@
Uri.parse("http://foo.com/test/sender/uri1");
Uri uri2 =
Uri.parse("http://foo.com/test/sender/uri2");
- Person person1 =
- TestConversationFactory.createMinimalPersonBuilder().setUri(
+ Person person1 = createMinimalPersonBuilder().setUri(
uri1.toString()).build();
- Person person2 =
- TestConversationFactory.createMinimalPersonBuilder().setName(
+ Person person2 = createMinimalPersonBuilder().setName(
uri2.toString()).build();
assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
@@ -95,10 +87,8 @@
@Test
public void equalsAndHashCode_differentBot_areNotEqual() {
- Person person1 =
- TestConversationFactory.createMinimalPersonBuilder().setBot(true).build();
- Person person2 =
- TestConversationFactory.createMinimalPersonBuilder().setBot(false).build();
+ Person person1 = createMinimalPersonBuilder().setBot(true).build();
+ Person person2 = createMinimalPersonBuilder().setBot(false).build();
assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
@@ -107,13 +97,19 @@
@Test
public void equalsAndHashCode_differentImportant_areNotEqual() {
- Person person1 =
- TestConversationFactory.createMinimalPersonBuilder().setImportant(true).build();
- Person person2 =
- TestConversationFactory.createMinimalPersonBuilder().setImportant(false).build();
+ Person person1 = createMinimalPersonBuilder().setImportant(true).build();
+ Person person2 = createMinimalPersonBuilder().setImportant(false).build();
assertThat(PersonsEqualityHelper.arePersonsEqual(person1, person2)).isFalse();
assertThat(PersonsEqualityHelper.getPersonHashCode(person1)).isNotEqualTo(
PersonsEqualityHelper.getPersonHashCode(person2));
}
+
+ private Person.Builder createMinimalPersonBuilder() {
+ return new Person.Builder();
+ }
+
+ private Person createMinimalPerson() {
+ return createMinimalPersonBuilder().build();
+ }
}
diff --git a/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java b/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java
index dc3097b..bd1274a 100644
--- a/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java
+++ b/car/app/app/src/test/java/androidx/car/app/messaging/model/TestConversationFactory.java
@@ -53,8 +53,8 @@
*
* <p>This method fills in the minimum required data to create a valid {@link Person}.
*/
- public static Person.Builder createMinimalPersonBuilder() {
- return new Person.Builder().setName("Person Name");
+ public static Person.Builder createMinimalMessageSenderBuilder() {
+ return new Person.Builder().setName("Person Name").setKey("sender_key");
}
/**
@@ -62,8 +62,8 @@
*
* <p>This method fills in the minimum required data to create a valid {@link Person}.
*/
- private static Person createMinimalPerson() {
- return createMinimalPersonBuilder().build();
+ private static Person createMinimalMessageSender() {
+ return createMinimalMessageSenderBuilder().build();
}
/**
@@ -72,7 +72,7 @@
* <p>This method fills in the minimum required data to create a valid {@link Person}.
*/
public static Person.Builder createFullyPopulatedPersonBuilder() {
- return createMinimalPersonBuilder()
+ return createMinimalMessageSenderBuilder()
.setKey("Foo Person")
.setIcon(TEST_SENDER_ICON)
.setUri(TEST_SENDER_URI.toString())
@@ -146,7 +146,7 @@
return new ConversationItem.Builder()
.setId("conversation_id")
.setTitle(CarText.create("Conversation Title"))
- .setSelf(createMinimalPerson())
+ .setSelf(createMinimalMessageSender())
.setMessages(messages)
.setConversationCallback(EMPTY_CONVERSATION_CALLBACK);
}
diff --git a/car/app/app/src/test/java/androidx/car/app/model/TabTest.java b/car/app/app/src/test/java/androidx/car/app/model/TabTest.java
index 14a5e80..2b9251b 100644
--- a/car/app/app/src/test/java/androidx/car/app/model/TabTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/model/TabTest.java
@@ -108,22 +108,22 @@
}
@Test
- public void equals_Builder() {
- Tab tab = TEST_TAB.toBuilder().build();
+ public void equals_copy() {
+ Tab tab = new Tab.Builder(TEST_TAB).build();
assertEquals(tab, TEST_TAB);
}
@Test
public void notEquals_differentTitle() {
- Tab tab = TEST_TAB.toBuilder().setTitle("New Tab").build();
+ Tab tab = new Tab.Builder(TEST_TAB).setTitle("New Tab").build();
assertNotEquals(tab, TEST_TAB);
}
@Test
public void notEquals_differentIcon() {
- Tab tab = TEST_TAB.toBuilder()
+ Tab tab = new Tab.Builder(TEST_TAB)
.setIcon(TestUtils.getTestCarIcon(
ApplicationProvider.getApplicationContext(),
"ic_test_2"))
@@ -134,7 +134,7 @@
@Test
public void notEquals_differentContentId() {
- Tab tab = TEST_TAB.toBuilder().setContentId("new id").build();
+ Tab tab = new Tab.Builder(TEST_TAB).setContentId("new id").build();
assertNotEquals(tab, TEST_TAB);
}
diff --git a/collection/collection/api/api_lint.ignore b/collection/collection/api/api_lint.ignore
index b0605dd..c3a23ac 100644
--- a/collection/collection/api/api_lint.ignore
+++ b/collection/collection/api/api_lint.ignore
@@ -1,14 +1,14 @@
// Baseline format: 1.0
ArrayReturn: androidx.collection.ArraySet#ArraySet(E[]) parameter #0:
Method parameter should be Collection<E> (or subclass) instead of raw array; was `E[]`
-ArrayReturn: androidx.collection.ArraySet#toArray():
- Method should return Collection<Object> (or subclass) instead of raw array; was `java.lang.Object[]`
-ArrayReturn: androidx.collection.ArraySet#toArray(T[]):
- Method should return Collection<T> (or subclass) instead of raw array; was `T[]`
ArrayReturn: androidx.collection.ArraySet#toArray(T[]) parameter #0:
Method parameter should be Collection<T> (or subclass) instead of raw array; was `T[]`
+GetterSetterNames: androidx.collection.SparseArrayCompat#getIsEmpty():
+ Getter for boolean property `isEmpty` is named `getIsEmpty` but should match the property name. Use `@get:JvmName` to rename.
+
+
KotlinOperator: androidx.collection.SparseArrayCompat#get(int, E):
Note that adding the `operator` keyword would allow calling this method using operator syntax
diff --git a/collection/collection/api/current.ignore b/collection/collection/api/current.ignore
index 6397290..7be6378 100644
--- a/collection/collection/api/current.ignore
+++ b/collection/collection/api/current.ignore
@@ -9,6 +9,18 @@
Method androidx.collection.SparseArrayCompat.clone has changed return type from androidx.collection.SparseArrayCompat<E!> to androidx.collection.SparseArrayCompat<E>
+InvalidNullConversion: androidx.collection.ArraySet#add(E) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.add(E element)
+InvalidNullConversion: androidx.collection.ArraySet#contains(E) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.contains(E element)
+InvalidNullConversion: androidx.collection.ArraySet#remove(E) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.remove(E element)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#containsKey(K) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.containsKey(K key)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#indexOfKey(K) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.indexOfKey(K key)
+
+
RemovedMethod: androidx.collection.ArraySet#ArraySet(androidx.collection.ArraySet<E>):
Removed constructor androidx.collection.ArraySet(androidx.collection.ArraySet<E>)
RemovedMethod: androidx.collection.ArraySet#ArraySet(java.util.Collection<E>):
diff --git a/collection/collection/api/current.txt b/collection/collection/api/current.txt
index 19c0d55..3fbf783 100644
--- a/collection/collection/api/current.txt
+++ b/collection/collection/api/current.txt
@@ -29,25 +29,25 @@
ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
ctor public ArraySet(java.util.Collection<? extends E>? set);
ctor public ArraySet(E![]? array);
- method public boolean add(E? element);
+ method public boolean add(E element);
method public void addAll(androidx.collection.ArraySet<? extends E> array);
method public boolean addAll(java.util.Collection<? extends E> elements);
method public void clear();
- method public operator boolean contains(E? element);
+ method public operator boolean contains(E element);
method public boolean containsAll(java.util.Collection<E!> elements);
method public void ensureCapacity(int minimumCapacity);
method public int getSize();
method public int indexOf(Object? key);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
- method public boolean remove(E? element);
+ method public boolean remove(E element);
method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
method public boolean removeAll(java.util.Collection<E!> elements);
- method public E! removeAt(int index);
+ method public E removeAt(int index);
method public boolean retainAll(java.util.Collection<E!> elements);
method public Object![] toArray();
method public <T> T![] toArray(T![] array);
- method public E! valueAt(int index);
+ method public E valueAt(int index);
property public int size;
}
@@ -59,15 +59,15 @@
public final class CircularArray<E> {
ctor public CircularArray(optional int minCapacity);
ctor public CircularArray();
- method public void addFirst(E? element);
- method public void addLast(E? element);
+ method public void addFirst(E element);
+ method public void addLast(E element);
method public void clear();
- method public operator E! get(int index);
+ method public operator E get(int index);
method public E! getFirst();
method public E! getLast();
method public boolean isEmpty();
- method public E! popFirst();
- method public E! popLast();
+ method public E popFirst();
+ method public E popLast();
method public void removeFromEnd(int count);
method public void removeFromStart(int count);
method public int size();
@@ -97,42 +97,42 @@
public class LongSparseArray<E> implements java.lang.Cloneable {
ctor public LongSparseArray(optional int initialCapacity);
ctor public LongSparseArray();
- method public void append(long key, E? value);
+ method public void append(long key, E value);
method public void clear();
method public androidx.collection.LongSparseArray<E> clone();
method public boolean containsKey(long key);
- method public boolean containsValue(E? value);
+ method public boolean containsValue(E value);
method @Deprecated public void delete(long key);
method public operator E? get(long key);
- method public E! get(long key, E? defaultValue);
+ method public E get(long key, E defaultValue);
method public int indexOfKey(long key);
- method public int indexOfValue(E? value);
+ method public int indexOfValue(E value);
method public boolean isEmpty();
method public long keyAt(int index);
- method public void put(long key, E? value);
+ method public void put(long key, E value);
method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
- method public E? putIfAbsent(long key, E? value);
+ method public E? putIfAbsent(long key, E value);
method public void remove(long key);
- method public boolean remove(long key, E? value);
+ method public boolean remove(long key, E value);
method public void removeAt(int index);
- method public E? replace(long key, E? value);
- method public boolean replace(long key, E? oldValue, E? newValue);
- method public void setValueAt(int index, E? value);
+ method public E? replace(long key, E value);
+ method public boolean replace(long key, E oldValue, E newValue);
+ method public void setValueAt(int index, E value);
method public int size();
- method public E! valueAt(int index);
+ method public E valueAt(int index);
}
public final class LongSparseArrayKt {
method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T? defaultValue);
- method public static inline <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+ method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
- method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T? value);
- method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T? value);
+ method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+ method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
}
@@ -166,69 +166,69 @@
ctor public SimpleArrayMap();
ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
method public void clear();
- method public boolean containsKey(K? key);
- method public boolean containsValue(V? value);
+ method public boolean containsKey(K key);
+ method public boolean containsValue(V value);
method public void ensureCapacity(int minimumCapacity);
- method public operator V? get(K? key);
- method public V! getOrDefault(Object? key, V? defaultValue);
- method public int indexOfKey(K? key);
+ method public operator V? get(K key);
+ method public V getOrDefault(Object? key, V defaultValue);
+ method public int indexOfKey(K key);
method public boolean isEmpty();
- method public K! keyAt(int index);
- method public V? put(K? key, V? value);
+ method public K keyAt(int index);
+ method public V? put(K key, V value);
method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
- method public V? putIfAbsent(K? key, V? value);
- method public V? remove(K? key);
- method public boolean remove(K? key, V? value);
- method public V! removeAt(int index);
- method public V? replace(K? key, V? value);
- method public boolean replace(K? key, V? oldValue, V? newValue);
- method public V! setValueAt(int index, V? value);
+ method public V? putIfAbsent(K key, V value);
+ method public V? remove(K key);
+ method public boolean remove(K key, V value);
+ method public V removeAt(int index);
+ method public V? replace(K key, V value);
+ method public boolean replace(K key, V oldValue, V newValue);
+ method public V setValueAt(int index, V value);
method public int size();
- method public V! valueAt(int index);
+ method public V valueAt(int index);
}
public class SparseArrayCompat<E> implements java.lang.Cloneable {
ctor public SparseArrayCompat(optional int initialCapacity);
ctor public SparseArrayCompat();
- method public void append(int key, E? value);
+ method public void append(int key, E value);
method public void clear();
method public androidx.collection.SparseArrayCompat<E> clone();
method public boolean containsKey(int key);
- method public boolean containsValue(E? value);
+ method public boolean containsValue(E value);
method @Deprecated public void delete(int key);
method public operator E? get(int key);
- method public E! get(int key, E? defaultValue);
+ method public E get(int key, E defaultValue);
method public final boolean getIsEmpty();
method public int indexOfKey(int key);
- method public int indexOfValue(E? value);
+ method public int indexOfValue(E value);
method public boolean isEmpty();
method public int keyAt(int index);
- method public void put(int key, E? value);
+ method public void put(int key, E value);
method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
- method public E? putIfAbsent(int key, E? value);
+ method public E? putIfAbsent(int key, E value);
method public void remove(int key);
method public boolean remove(int key, Object? value);
method public void removeAt(int index);
method public void removeAtRange(int index, int size);
- method public E? replace(int key, E? value);
- method public boolean replace(int key, E? oldValue, E? newValue);
- method public void setValueAt(int index, E? value);
+ method public E? replace(int key, E value);
+ method public boolean replace(int key, E oldValue, E newValue);
+ method public void setValueAt(int index, E value);
method public int size();
- method public E! valueAt(int index);
+ method public E valueAt(int index);
property public final boolean isEmpty;
}
public final class SparseArrayKt {
method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T? defaultValue);
- method public static inline <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+ method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
- method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T? value);
- method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T? value);
+ method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+ method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
}
diff --git a/collection/collection/api/public_plus_experimental_current.txt b/collection/collection/api/public_plus_experimental_current.txt
index 19c0d55..3fbf783 100644
--- a/collection/collection/api/public_plus_experimental_current.txt
+++ b/collection/collection/api/public_plus_experimental_current.txt
@@ -29,25 +29,25 @@
ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
ctor public ArraySet(java.util.Collection<? extends E>? set);
ctor public ArraySet(E![]? array);
- method public boolean add(E? element);
+ method public boolean add(E element);
method public void addAll(androidx.collection.ArraySet<? extends E> array);
method public boolean addAll(java.util.Collection<? extends E> elements);
method public void clear();
- method public operator boolean contains(E? element);
+ method public operator boolean contains(E element);
method public boolean containsAll(java.util.Collection<E!> elements);
method public void ensureCapacity(int minimumCapacity);
method public int getSize();
method public int indexOf(Object? key);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
- method public boolean remove(E? element);
+ method public boolean remove(E element);
method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
method public boolean removeAll(java.util.Collection<E!> elements);
- method public E! removeAt(int index);
+ method public E removeAt(int index);
method public boolean retainAll(java.util.Collection<E!> elements);
method public Object![] toArray();
method public <T> T![] toArray(T![] array);
- method public E! valueAt(int index);
+ method public E valueAt(int index);
property public int size;
}
@@ -59,15 +59,15 @@
public final class CircularArray<E> {
ctor public CircularArray(optional int minCapacity);
ctor public CircularArray();
- method public void addFirst(E? element);
- method public void addLast(E? element);
+ method public void addFirst(E element);
+ method public void addLast(E element);
method public void clear();
- method public operator E! get(int index);
+ method public operator E get(int index);
method public E! getFirst();
method public E! getLast();
method public boolean isEmpty();
- method public E! popFirst();
- method public E! popLast();
+ method public E popFirst();
+ method public E popLast();
method public void removeFromEnd(int count);
method public void removeFromStart(int count);
method public int size();
@@ -97,42 +97,42 @@
public class LongSparseArray<E> implements java.lang.Cloneable {
ctor public LongSparseArray(optional int initialCapacity);
ctor public LongSparseArray();
- method public void append(long key, E? value);
+ method public void append(long key, E value);
method public void clear();
method public androidx.collection.LongSparseArray<E> clone();
method public boolean containsKey(long key);
- method public boolean containsValue(E? value);
+ method public boolean containsValue(E value);
method @Deprecated public void delete(long key);
method public operator E? get(long key);
- method public E! get(long key, E? defaultValue);
+ method public E get(long key, E defaultValue);
method public int indexOfKey(long key);
- method public int indexOfValue(E? value);
+ method public int indexOfValue(E value);
method public boolean isEmpty();
method public long keyAt(int index);
- method public void put(long key, E? value);
+ method public void put(long key, E value);
method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
- method public E? putIfAbsent(long key, E? value);
+ method public E? putIfAbsent(long key, E value);
method public void remove(long key);
- method public boolean remove(long key, E? value);
+ method public boolean remove(long key, E value);
method public void removeAt(int index);
- method public E? replace(long key, E? value);
- method public boolean replace(long key, E? oldValue, E? newValue);
- method public void setValueAt(int index, E? value);
+ method public E? replace(long key, E value);
+ method public boolean replace(long key, E oldValue, E newValue);
+ method public void setValueAt(int index, E value);
method public int size();
- method public E! valueAt(int index);
+ method public E valueAt(int index);
}
public final class LongSparseArrayKt {
method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T? defaultValue);
- method public static inline <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+ method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
- method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T? value);
- method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T? value);
+ method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+ method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
}
@@ -166,69 +166,69 @@
ctor public SimpleArrayMap();
ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
method public void clear();
- method public boolean containsKey(K? key);
- method public boolean containsValue(V? value);
+ method public boolean containsKey(K key);
+ method public boolean containsValue(V value);
method public void ensureCapacity(int minimumCapacity);
- method public operator V? get(K? key);
- method public V! getOrDefault(Object? key, V? defaultValue);
- method public int indexOfKey(K? key);
+ method public operator V? get(K key);
+ method public V getOrDefault(Object? key, V defaultValue);
+ method public int indexOfKey(K key);
method public boolean isEmpty();
- method public K! keyAt(int index);
- method public V? put(K? key, V? value);
+ method public K keyAt(int index);
+ method public V? put(K key, V value);
method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
- method public V? putIfAbsent(K? key, V? value);
- method public V? remove(K? key);
- method public boolean remove(K? key, V? value);
- method public V! removeAt(int index);
- method public V? replace(K? key, V? value);
- method public boolean replace(K? key, V? oldValue, V? newValue);
- method public V! setValueAt(int index, V? value);
+ method public V? putIfAbsent(K key, V value);
+ method public V? remove(K key);
+ method public boolean remove(K key, V value);
+ method public V removeAt(int index);
+ method public V? replace(K key, V value);
+ method public boolean replace(K key, V oldValue, V newValue);
+ method public V setValueAt(int index, V value);
method public int size();
- method public V! valueAt(int index);
+ method public V valueAt(int index);
}
public class SparseArrayCompat<E> implements java.lang.Cloneable {
ctor public SparseArrayCompat(optional int initialCapacity);
ctor public SparseArrayCompat();
- method public void append(int key, E? value);
+ method public void append(int key, E value);
method public void clear();
method public androidx.collection.SparseArrayCompat<E> clone();
method public boolean containsKey(int key);
- method public boolean containsValue(E? value);
+ method public boolean containsValue(E value);
method @Deprecated public void delete(int key);
method public operator E? get(int key);
- method public E! get(int key, E? defaultValue);
+ method public E get(int key, E defaultValue);
method public final boolean getIsEmpty();
method public int indexOfKey(int key);
- method public int indexOfValue(E? value);
+ method public int indexOfValue(E value);
method public boolean isEmpty();
method public int keyAt(int index);
- method public void put(int key, E? value);
+ method public void put(int key, E value);
method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
- method public E? putIfAbsent(int key, E? value);
+ method public E? putIfAbsent(int key, E value);
method public void remove(int key);
method public boolean remove(int key, Object? value);
method public void removeAt(int index);
method public void removeAtRange(int index, int size);
- method public E? replace(int key, E? value);
- method public boolean replace(int key, E? oldValue, E? newValue);
- method public void setValueAt(int index, E? value);
+ method public E? replace(int key, E value);
+ method public boolean replace(int key, E oldValue, E newValue);
+ method public void setValueAt(int index, E value);
method public int size();
- method public E! valueAt(int index);
+ method public E valueAt(int index);
property public final boolean isEmpty;
}
public final class SparseArrayKt {
method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T? defaultValue);
- method public static inline <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+ method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
- method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T? value);
- method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T? value);
+ method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+ method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
}
diff --git a/collection/collection/api/restricted_current.ignore b/collection/collection/api/restricted_current.ignore
index 6397290..7be6378 100644
--- a/collection/collection/api/restricted_current.ignore
+++ b/collection/collection/api/restricted_current.ignore
@@ -9,6 +9,18 @@
Method androidx.collection.SparseArrayCompat.clone has changed return type from androidx.collection.SparseArrayCompat<E!> to androidx.collection.SparseArrayCompat<E>
+InvalidNullConversion: androidx.collection.ArraySet#add(E) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.add(E element)
+InvalidNullConversion: androidx.collection.ArraySet#contains(E) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.contains(E element)
+InvalidNullConversion: androidx.collection.ArraySet#remove(E) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.collection.ArraySet.remove(E element)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#containsKey(K) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.containsKey(K key)
+InvalidNullConversion: androidx.collection.SimpleArrayMap#indexOfKey(K) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.collection.SimpleArrayMap.indexOfKey(K key)
+
+
RemovedMethod: androidx.collection.ArraySet#ArraySet(androidx.collection.ArraySet<E>):
Removed constructor androidx.collection.ArraySet(androidx.collection.ArraySet<E>)
RemovedMethod: androidx.collection.ArraySet#ArraySet(java.util.Collection<E>):
diff --git a/collection/collection/api/restricted_current.txt b/collection/collection/api/restricted_current.txt
index 19c0d55..3fbf783 100644
--- a/collection/collection/api/restricted_current.txt
+++ b/collection/collection/api/restricted_current.txt
@@ -29,25 +29,25 @@
ctor public ArraySet(androidx.collection.ArraySet<? extends E>? set);
ctor public ArraySet(java.util.Collection<? extends E>? set);
ctor public ArraySet(E![]? array);
- method public boolean add(E? element);
+ method public boolean add(E element);
method public void addAll(androidx.collection.ArraySet<? extends E> array);
method public boolean addAll(java.util.Collection<? extends E> elements);
method public void clear();
- method public operator boolean contains(E? element);
+ method public operator boolean contains(E element);
method public boolean containsAll(java.util.Collection<E!> elements);
method public void ensureCapacity(int minimumCapacity);
method public int getSize();
method public int indexOf(Object? key);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
- method public boolean remove(E? element);
+ method public boolean remove(E element);
method public boolean removeAll(androidx.collection.ArraySet<? extends E> array);
method public boolean removeAll(java.util.Collection<E!> elements);
- method public E! removeAt(int index);
+ method public E removeAt(int index);
method public boolean retainAll(java.util.Collection<E!> elements);
method public Object![] toArray();
method public <T> T![] toArray(T![] array);
- method public E! valueAt(int index);
+ method public E valueAt(int index);
property public int size;
}
@@ -59,15 +59,15 @@
public final class CircularArray<E> {
ctor public CircularArray(optional int minCapacity);
ctor public CircularArray();
- method public void addFirst(E? element);
- method public void addLast(E? element);
+ method public void addFirst(E element);
+ method public void addLast(E element);
method public void clear();
- method public operator E! get(int index);
+ method public operator E get(int index);
method public E! getFirst();
method public E! getLast();
method public boolean isEmpty();
- method public E! popFirst();
- method public E! popLast();
+ method public E popFirst();
+ method public E popLast();
method public void removeFromEnd(int count);
method public void removeFromStart(int count);
method public int size();
@@ -97,42 +97,42 @@
public class LongSparseArray<E> implements java.lang.Cloneable {
ctor public LongSparseArray(optional int initialCapacity);
ctor public LongSparseArray();
- method public void append(long key, E? value);
+ method public void append(long key, E value);
method public void clear();
method public androidx.collection.LongSparseArray<E> clone();
method public boolean containsKey(long key);
- method public boolean containsValue(E? value);
+ method public boolean containsValue(E value);
method @Deprecated public void delete(long key);
method public operator E? get(long key);
- method public E! get(long key, E? defaultValue);
+ method public E get(long key, E defaultValue);
method public int indexOfKey(long key);
- method public int indexOfValue(E? value);
+ method public int indexOfValue(E value);
method public boolean isEmpty();
method public long keyAt(int index);
- method public void put(long key, E? value);
+ method public void put(long key, E value);
method public void putAll(androidx.collection.LongSparseArray<? extends E> other);
- method public E? putIfAbsent(long key, E? value);
+ method public E? putIfAbsent(long key, E value);
method public void remove(long key);
- method public boolean remove(long key, E? value);
+ method public boolean remove(long key, E value);
method public void removeAt(int index);
- method public E? replace(long key, E? value);
- method public boolean replace(long key, E? oldValue, E? newValue);
- method public void setValueAt(int index, E? value);
+ method public E? replace(long key, E value);
+ method public boolean replace(long key, E oldValue, E newValue);
+ method public void setValueAt(int index, E value);
method public int size();
- method public E! valueAt(int index);
+ method public E valueAt(int index);
}
public final class LongSparseArrayKt {
method public static inline operator <T> boolean contains(androidx.collection.LongSparseArray<T>, long key);
method public static inline <T> void forEach(androidx.collection.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(androidx.collection.LongSparseArray<T>, long key, T? defaultValue);
- method public static inline <T> T! getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(androidx.collection.LongSparseArray<T>, long key, T defaultValue);
+ method public static inline <T> T getOrElse(androidx.collection.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(androidx.collection.LongSparseArray<T>);
method public static inline <T> boolean isNotEmpty(androidx.collection.LongSparseArray<T>);
method public static <T> kotlin.collections.LongIterator keyIterator(androidx.collection.LongSparseArray<T>);
method public static operator <T> androidx.collection.LongSparseArray<T> plus(androidx.collection.LongSparseArray<T>, androidx.collection.LongSparseArray<T> other);
- method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T? value);
- method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T? value);
+ method @Deprecated public static <T> boolean remove(androidx.collection.LongSparseArray<T>, long key, T value);
+ method public static inline operator <T> void set(androidx.collection.LongSparseArray<T>, long key, T value);
method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.LongSparseArray<T>);
}
@@ -166,69 +166,69 @@
ctor public SimpleArrayMap();
ctor public SimpleArrayMap(androidx.collection.SimpleArrayMap<? extends K,? extends V>? map);
method public void clear();
- method public boolean containsKey(K? key);
- method public boolean containsValue(V? value);
+ method public boolean containsKey(K key);
+ method public boolean containsValue(V value);
method public void ensureCapacity(int minimumCapacity);
- method public operator V? get(K? key);
- method public V! getOrDefault(Object? key, V? defaultValue);
- method public int indexOfKey(K? key);
+ method public operator V? get(K key);
+ method public V getOrDefault(Object? key, V defaultValue);
+ method public int indexOfKey(K key);
method public boolean isEmpty();
- method public K! keyAt(int index);
- method public V? put(K? key, V? value);
+ method public K keyAt(int index);
+ method public V? put(K key, V value);
method public void putAll(androidx.collection.SimpleArrayMap<? extends K,? extends V> map);
- method public V? putIfAbsent(K? key, V? value);
- method public V? remove(K? key);
- method public boolean remove(K? key, V? value);
- method public V! removeAt(int index);
- method public V? replace(K? key, V? value);
- method public boolean replace(K? key, V? oldValue, V? newValue);
- method public V! setValueAt(int index, V? value);
+ method public V? putIfAbsent(K key, V value);
+ method public V? remove(K key);
+ method public boolean remove(K key, V value);
+ method public V removeAt(int index);
+ method public V? replace(K key, V value);
+ method public boolean replace(K key, V oldValue, V newValue);
+ method public V setValueAt(int index, V value);
method public int size();
- method public V! valueAt(int index);
+ method public V valueAt(int index);
}
public class SparseArrayCompat<E> implements java.lang.Cloneable {
ctor public SparseArrayCompat(optional int initialCapacity);
ctor public SparseArrayCompat();
- method public void append(int key, E? value);
+ method public void append(int key, E value);
method public void clear();
method public androidx.collection.SparseArrayCompat<E> clone();
method public boolean containsKey(int key);
- method public boolean containsValue(E? value);
+ method public boolean containsValue(E value);
method @Deprecated public void delete(int key);
method public operator E? get(int key);
- method public E! get(int key, E? defaultValue);
+ method public E get(int key, E defaultValue);
method public final boolean getIsEmpty();
method public int indexOfKey(int key);
- method public int indexOfValue(E? value);
+ method public int indexOfValue(E value);
method public boolean isEmpty();
method public int keyAt(int index);
- method public void put(int key, E? value);
+ method public void put(int key, E value);
method public void putAll(androidx.collection.SparseArrayCompat<? extends E> other);
- method public E? putIfAbsent(int key, E? value);
+ method public E? putIfAbsent(int key, E value);
method public void remove(int key);
method public boolean remove(int key, Object? value);
method public void removeAt(int index);
method public void removeAtRange(int index, int size);
- method public E? replace(int key, E? value);
- method public boolean replace(int key, E? oldValue, E? newValue);
- method public void setValueAt(int index, E? value);
+ method public E? replace(int key, E value);
+ method public boolean replace(int key, E oldValue, E newValue);
+ method public void setValueAt(int index, E value);
method public int size();
- method public E! valueAt(int index);
+ method public E valueAt(int index);
property public final boolean isEmpty;
}
public final class SparseArrayKt {
method public static inline operator <T> boolean contains(androidx.collection.SparseArrayCompat<T>, int key);
method public static inline <T> void forEach(androidx.collection.SparseArrayCompat<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T? defaultValue);
- method public static inline <T> T! getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(androidx.collection.SparseArrayCompat<T>, int key, T defaultValue);
+ method public static inline <T> T getOrElse(androidx.collection.SparseArrayCompat<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(androidx.collection.SparseArrayCompat<T>);
method public static inline <T> boolean isNotEmpty(androidx.collection.SparseArrayCompat<T>);
method public static <T> kotlin.collections.IntIterator keyIterator(androidx.collection.SparseArrayCompat<T>);
method public static operator <T> androidx.collection.SparseArrayCompat<T> plus(androidx.collection.SparseArrayCompat<T>, androidx.collection.SparseArrayCompat<T> other);
- method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T? value);
- method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T? value);
+ method @Deprecated public static <T> boolean remove(androidx.collection.SparseArrayCompat<T>, int key, T value);
+ method public static inline operator <T> void set(androidx.collection.SparseArrayCompat<T>, int key, T value);
method public static <T> java.util.Iterator<T> valueIterator(androidx.collection.SparseArrayCompat<T>);
}
diff --git a/compose/animation/animation-core/api/current.ignore b/compose/animation/animation-core/api/current.ignore
new file mode 100644
index 0000000..b54a96a
--- /dev/null
+++ b/compose/animation/animation-core/api/current.ignore
@@ -0,0 +1,75 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T, String) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold, String label)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateDecay(T, androidx.compose.animation.core.DecayAnimationSpec<T>, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg4)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#snapTo(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #4:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationState#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, V, long, long, boolean) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#copy(androidx.compose.animation.core.AnimationState<T,V>, T, V, long, long, boolean) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.copy(androidx.compose.animation.core.AnimationState<T,V> arg1, T value, V velocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V> arg1, T value)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#at(T, int) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.at(T arg1, int timeStamp)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#atFraction(T, float) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.atFraction(T arg1, float fraction)
+InvalidNullConversion: androidx.compose.animation.core.MutableTransitionState#MutableTransitionState(S) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialState in androidx.compose.animation.core.MutableTransitionState(S initialState)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animateTo(androidx.compose.animation.core.AnimationState<T,V>, T, androidx.compose.animation.core.AnimationSpec<T>, boolean, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animateTo(androidx.compose.animation.core.AnimationState<T,V> arg1, T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, boolean sequentialAnimation, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg6)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#updateTransition(T, String) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.TransitionKt.updateTransition(T targetState, String label)
diff --git a/compose/animation/animation-core/api/current.txt b/compose/animation/animation-core/api/current.txt
index dca6624..ac05bf2 100644
--- a/compose/animation/animation-core/api/current.txt
+++ b/compose/animation/animation-core/api/current.txt
@@ -2,27 +2,27 @@
package androidx.compose.animation.core {
public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
- ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
- ctor @Deprecated public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
- method public suspend Object? animateDecay(T? initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
- method public suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+ ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+ ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+ method public suspend Object? animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+ method public suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
method public androidx.compose.runtime.State<T> asState();
method public String getLabel();
method public T? getLowerBound();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
method public T? getUpperBound();
method public T! getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
- method public suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? stop(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public void updateBounds(optional T? lowerBound, optional T? upperBound);
property public final boolean isRunning;
property public final String label;
property public final T? lowerBound;
- property public final T! targetValue;
+ property public final T targetValue;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
property public final T? upperBound;
property public final T! value;
@@ -51,21 +51,21 @@
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends androidx.compose.ui.geometry.Rect> animateRectAsState(androidx.compose.ui.geometry.Rect targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Rect> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Rect,? extends kotlin.Unit>? finishedListener);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,kotlin.Unit>? finishedListener);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,? extends kotlin.Unit>? finishedListener);
- method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
- method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValueAsState(T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>? finishedListener);
+ method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>? finishedListener);
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface Animation<T, V extends androidx.compose.animation.core.AnimationVector> {
method public long getDurationNanos();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public default boolean isFinishedFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public abstract long durationNanos;
property public abstract boolean isInfinite;
- property public abstract T! targetValue;
+ property public abstract T targetValue;
property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -84,8 +84,8 @@
public final class AnimationKt {
method public static androidx.compose.animation.core.DecayAnimation<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> DecayAnimation(androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, float initialValue, optional float initialVelocity);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, T? initialVelocity);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> T! getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> T getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
}
public final class AnimationResult<T, V extends androidx.compose.animation.core.AnimationVector> {
@@ -101,9 +101,9 @@
method public long getFinishedTimeNanos();
method public long getLastFrameTimeNanos();
method public long getStartTimeNanos();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
@@ -112,9 +112,9 @@
property public final boolean isRunning;
property public final long lastFrameTimeNanos;
property public final long startTimeNanos;
- property public final T! targetValue;
+ property public final T targetValue;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public final T! value;
+ property public final T value;
property public final T! velocity;
property public final V velocityVector;
}
@@ -135,11 +135,11 @@
}
public final class AnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
- ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
method public long getFinishedTimeNanos();
method public long getLastFrameTimeNanos();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
@@ -147,17 +147,17 @@
property public final boolean isRunning;
property public final long lastFrameTimeNanos;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
property public final T! velocity;
property public final V velocityVector;
}
public final class AnimationStateKt {
method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> AnimationState(float initialValue, optional float initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T? value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> copy(androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D>, optional float value, optional float velocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T? value);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T value);
method public static boolean isFinished(androidx.compose.animation.core.AnimationState<?,?>);
}
@@ -213,22 +213,22 @@
}
public final class DecayAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
- ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
- ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
- ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+ ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+ ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+ ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
method public long getDurationNanos();
- method public T! getInitialValue();
+ method public T getInitialValue();
method public V getInitialVelocityVector();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public long durationNanos;
- property public final T! initialValue;
+ property public final T initialValue;
property public final V initialVelocityVector;
property public boolean isInfinite;
- property public T! targetValue;
+ property public T targetValue;
property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -237,7 +237,7 @@
}
public final class DecayAnimationSpecKt {
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> T! calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> T calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
method public static float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float initialVelocity);
method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> exponentialDecay(optional float frictionMultiplier, optional float absVelocityThreshold);
method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> generateDecayAnimationSpec(androidx.compose.animation.core.FloatDecayAnimationSpec);
@@ -415,19 +415,19 @@
method public androidx.compose.animation.core.AnimationSpec<T> getAnimationSpec();
method public String getLabel();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
property public final androidx.compose.animation.core.AnimationSpec<T> animationSpec;
property public final String label;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
}
public final class InfiniteTransitionKt {
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec, optional String label);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec);
- method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T? initialValue, T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
- method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValue(androidx.compose.animation.core.InfiniteTransition, T? initialValue, T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
+ method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
method @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
}
@@ -444,8 +444,8 @@
public static final class KeyframesSpec.KeyframesSpecConfig<T> {
ctor public KeyframesSpec.KeyframesSpecConfig();
- method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T?, int timeStamp);
- method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T?, float fraction);
+ method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T, int timeStamp);
+ method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T, float fraction);
method public int getDelayMillis();
method public int getDurationMillis();
method public void setDelayMillis(int);
@@ -456,14 +456,14 @@
}
public final class MutableTransitionState<S> {
- ctor public MutableTransitionState(S? initialState);
- method public S! getCurrentState();
- method public S! getTargetState();
+ ctor public MutableTransitionState(S initialState);
+ method public S getCurrentState();
+ method public S getTargetState();
method public boolean isIdle();
method public void setTargetState(S!);
- property public final S! currentState;
+ property public final S currentState;
property public final boolean isIdle;
- property public final S! targetState;
+ property public final S targetState;
}
public enum RepeatMode {
@@ -543,25 +543,25 @@
public final class SuspendAnimationKt {
method public static suspend Object? animate(float initialValue, float targetValue, optional float initialVelocity, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public static suspend Object? animateDecay(float initialValue, float initialVelocity, androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateDecay(androidx.compose.animation.core.AnimationState<T,V>, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T? targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
public final class TargetBasedAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
- ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, optional V? initialVelocityVector);
+ ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional V? initialVelocityVector);
method public long getDurationNanos();
- method public T! getInitialValue();
- method public T! getTargetValue();
+ method public T getInitialValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public long durationNanos;
- property public final T! initialValue;
+ property public final T initialValue;
property public boolean isInfinite;
- property public T! targetValue;
+ property public T targetValue;
property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -570,7 +570,7 @@
method public S! getCurrentState();
method public String? getLabel();
method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
- method public S! getTargetState();
+ method public S getTargetState();
method public long getTotalDurationNanos();
method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
method public boolean isRunning();
@@ -579,17 +579,17 @@
property public final boolean isRunning;
property public final String? label;
property public final androidx.compose.animation.core.Transition.Segment<S> segment;
- property public final S! targetState;
+ property public final S targetState;
property public final long totalDurationNanos;
property public final java.util.List<androidx.compose.animation.core.Transition<?>> transitions;
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface Transition.Segment<S> {
- method public S! getInitialState();
- method public S! getTargetState();
- method public default infix boolean isTransitioningTo(S?, S? targetState);
- property public abstract S! initialState;
- property public abstract S! targetState;
+ method public S getInitialState();
+ method public S getTargetState();
+ method public default infix boolean isTransitioningTo(S, S targetState);
+ property public abstract S initialState;
+ property public abstract S targetState;
}
@androidx.compose.runtime.Stable public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
@@ -597,12 +597,12 @@
method public androidx.compose.animation.core.FiniteAnimationSpec<T> getAnimationSpec();
method public String getLabel();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
property public final androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec;
property public final String label;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
}
public final class TransitionKt {
@@ -615,7 +615,7 @@
method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRect(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Rect>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Rect> targetValueByState);
method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Size>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Size> targetValueByState);
method @androidx.compose.runtime.Composable public static inline <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.Transition<S>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<T>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> targetValueByState);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T? targetState, optional String? label);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional String? label);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(androidx.compose.animation.core.MutableTransitionState<T> transitionState, optional String? label);
}
diff --git a/compose/animation/animation-core/api/public_plus_experimental_current.txt b/compose/animation/animation-core/api/public_plus_experimental_current.txt
index 2084af1..03897cb 100644
--- a/compose/animation/animation-core/api/public_plus_experimental_current.txt
+++ b/compose/animation/animation-core/api/public_plus_experimental_current.txt
@@ -2,27 +2,27 @@
package androidx.compose.animation.core {
public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
- ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
- ctor @Deprecated public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
- method public suspend Object? animateDecay(T? initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
- method public suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+ ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+ ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+ method public suspend Object? animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+ method public suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
method public androidx.compose.runtime.State<T> asState();
method public String getLabel();
method public T? getLowerBound();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
method public T? getUpperBound();
method public T! getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
- method public suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? stop(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public void updateBounds(optional T? lowerBound, optional T? upperBound);
property public final boolean isRunning;
property public final String label;
property public final T? lowerBound;
- property public final T! targetValue;
+ property public final T targetValue;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
property public final T? upperBound;
property public final T! value;
@@ -51,21 +51,21 @@
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends androidx.compose.ui.geometry.Rect> animateRectAsState(androidx.compose.ui.geometry.Rect targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Rect> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Rect,? extends kotlin.Unit>? finishedListener);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,kotlin.Unit>? finishedListener);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,? extends kotlin.Unit>? finishedListener);
- method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
- method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValueAsState(T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>? finishedListener);
+ method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>? finishedListener);
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface Animation<T, V extends androidx.compose.animation.core.AnimationVector> {
method public long getDurationNanos();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public default boolean isFinishedFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public abstract long durationNanos;
property public abstract boolean isInfinite;
- property public abstract T! targetValue;
+ property public abstract T targetValue;
property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -84,8 +84,8 @@
public final class AnimationKt {
method public static androidx.compose.animation.core.DecayAnimation<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> DecayAnimation(androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, float initialValue, optional float initialVelocity);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, T? initialVelocity);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> T! getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> T getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
}
public final class AnimationResult<T, V extends androidx.compose.animation.core.AnimationVector> {
@@ -101,9 +101,9 @@
method public long getFinishedTimeNanos();
method public long getLastFrameTimeNanos();
method public long getStartTimeNanos();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
@@ -112,9 +112,9 @@
property public final boolean isRunning;
property public final long lastFrameTimeNanos;
property public final long startTimeNanos;
- property public final T! targetValue;
+ property public final T targetValue;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public final T! value;
+ property public final T value;
property public final T! velocity;
property public final V velocityVector;
}
@@ -135,11 +135,11 @@
}
public final class AnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
- ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
method public long getFinishedTimeNanos();
method public long getLastFrameTimeNanos();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
@@ -147,17 +147,17 @@
property public final boolean isRunning;
property public final long lastFrameTimeNanos;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
property public final T! velocity;
property public final V velocityVector;
}
public final class AnimationStateKt {
method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> AnimationState(float initialValue, optional float initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T? value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> copy(androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D>, optional float value, optional float velocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T? value);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T value);
method public static boolean isFinished(androidx.compose.animation.core.AnimationState<?,?>);
}
@@ -213,22 +213,22 @@
}
public final class DecayAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
- ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
- ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
- ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+ ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+ ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+ ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
method public long getDurationNanos();
- method public T! getInitialValue();
+ method public T getInitialValue();
method public V getInitialVelocityVector();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public long durationNanos;
- property public final T! initialValue;
+ property public final T initialValue;
property public final V initialVelocityVector;
property public boolean isInfinite;
- property public T! targetValue;
+ property public T targetValue;
property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -237,7 +237,7 @@
}
public final class DecayAnimationSpecKt {
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> T! calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> T calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
method public static float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float initialVelocity);
method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> exponentialDecay(optional float frictionMultiplier, optional float absVelocityThreshold);
method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> generateDecayAnimationSpec(androidx.compose.animation.core.FloatDecayAnimationSpec);
@@ -418,19 +418,19 @@
method public androidx.compose.animation.core.AnimationSpec<T> getAnimationSpec();
method public String getLabel();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
property public final androidx.compose.animation.core.AnimationSpec<T> animationSpec;
property public final String label;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
}
public final class InfiniteTransitionKt {
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec, optional String label);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec);
- method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T? initialValue, T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
- method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValue(androidx.compose.animation.core.InfiniteTransition, T? initialValue, T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
+ method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
method @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
}
@@ -450,8 +450,8 @@
public static final class KeyframesSpec.KeyframesSpecConfig<T> {
ctor public KeyframesSpec.KeyframesSpecConfig();
- method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T?, int timeStamp);
- method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T?, float fraction);
+ method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T, int timeStamp);
+ method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T, float fraction);
method public int getDelayMillis();
method public int getDurationMillis();
method public void setDelayMillis(int);
@@ -462,14 +462,14 @@
}
public final class MutableTransitionState<S> {
- ctor public MutableTransitionState(S? initialState);
- method public S! getCurrentState();
- method public S! getTargetState();
+ ctor public MutableTransitionState(S initialState);
+ method public S getCurrentState();
+ method public S getTargetState();
method public boolean isIdle();
method public void setTargetState(S!);
- property public final S! currentState;
+ property public final S currentState;
property public final boolean isIdle;
- property public final S! targetState;
+ property public final S targetState;
}
public enum RepeatMode {
@@ -549,25 +549,25 @@
public final class SuspendAnimationKt {
method public static suspend Object? animate(float initialValue, float targetValue, optional float initialVelocity, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public static suspend Object? animateDecay(float initialValue, float initialVelocity, androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateDecay(androidx.compose.animation.core.AnimationState<T,V>, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T? targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
public final class TargetBasedAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
- ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, optional V? initialVelocityVector);
+ ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional V? initialVelocityVector);
method public long getDurationNanos();
- method public T! getInitialValue();
- method public T! getTargetValue();
+ method public T getInitialValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public long durationNanos;
- property public final T! initialValue;
+ property public final T initialValue;
property public boolean isInfinite;
- property public T! targetValue;
+ property public T targetValue;
property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -576,7 +576,7 @@
method public S! getCurrentState();
method public String? getLabel();
method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
- method public S! getTargetState();
+ method public S getTargetState();
method public long getTotalDurationNanos();
method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
method public boolean isRunning();
@@ -585,17 +585,17 @@
property public final boolean isRunning;
property public final String? label;
property public final androidx.compose.animation.core.Transition.Segment<S> segment;
- property public final S! targetState;
+ property public final S targetState;
property public final long totalDurationNanos;
property public final java.util.List<androidx.compose.animation.core.Transition<?>> transitions;
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface Transition.Segment<S> {
- method public S! getInitialState();
- method public S! getTargetState();
- method public default infix boolean isTransitioningTo(S?, S? targetState);
- property public abstract S! initialState;
- property public abstract S! targetState;
+ method public S getInitialState();
+ method public S getTargetState();
+ method public default infix boolean isTransitioningTo(S, S targetState);
+ property public abstract S initialState;
+ property public abstract S targetState;
}
@androidx.compose.runtime.Stable public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
@@ -603,12 +603,12 @@
method public androidx.compose.animation.core.FiniteAnimationSpec<T> getAnimationSpec();
method public String getLabel();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
property public final androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec;
property public final String label;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
}
public final class TransitionKt {
@@ -622,7 +622,7 @@
method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Size>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Size> targetValueByState);
method @androidx.compose.runtime.Composable public static inline <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.Transition<S>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<T>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> targetValueByState);
method @androidx.compose.animation.core.ExperimentalTransitionApi @androidx.compose.runtime.Composable public static inline <S, T> androidx.compose.animation.core.Transition<T> createChildTransition(androidx.compose.animation.core.Transition<S>, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> transformToChildState);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T? targetState, optional String? label);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional String? label);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(androidx.compose.animation.core.MutableTransitionState<T> transitionState, optional String? label);
}
diff --git a/compose/animation/animation-core/api/restricted_current.ignore b/compose/animation/animation-core/api/restricted_current.ignore
new file mode 100644
index 0000000..5e16b5b
--- /dev/null
+++ b/compose/animation/animation-core/api/restricted_current.ignore
@@ -0,0 +1,83 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#Animatable(T, androidx.compose.animation.core.TwoWayConverter<T,V>, T, String) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T visibilityThreshold, String label)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateDecay(T, androidx.compose.animation.core.DecayAnimationSpec<T>, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg4)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#animateTo(T, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.Animatable.animateTo(T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T initialVelocity, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>> arg5)
+InvalidNullConversion: androidx.compose.animation.core.Animatable#snapTo(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.Animatable.snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimateAsStateKt#animateValueAsState(T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.AnimationSpec<T>, T, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimateAsStateKt.animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.AnimationSpec<T> animationSpec, T visibilityThreshold, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> finishedListener)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationKt#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T) parameter #4:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationKt.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.AnimationState#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, V, long, long, boolean) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, long, long, boolean) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.AnimationStateKt.AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#copy(androidx.compose.animation.core.AnimationState<T,V>, T, V, long, long, boolean) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.copy(androidx.compose.animation.core.AnimationState<T,V> arg1, T value, V velocityVector, long lastFrameTimeNanos, long finishedTimeNanos, boolean isRunning)
+InvalidNullConversion: androidx.compose.animation.core.AnimationStateKt#createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.animation.core.AnimationStateKt.createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V> arg1, T value)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimation#DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, V) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.DecayAnimationSpecKt#calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialVelocity in androidx.compose.animation.core.DecayAnimationSpecKt.calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T> arg1, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.InfiniteTransitionKt#animateValue(androidx.compose.animation.core.InfiniteTransition, T, T, androidx.compose.animation.core.TwoWayConverter<T,V>, androidx.compose.animation.core.InfiniteRepeatableSpec<T>, String) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.InfiniteTransitionKt.animateValue(androidx.compose.animation.core.InfiniteTransition arg1, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, String label)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#at(T, int) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.at(T arg1, int timeStamp)
+InvalidNullConversion: androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig#atFraction(T, float) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig.atFraction(T arg1, float fraction)
+InvalidNullConversion: androidx.compose.animation.core.MutableTransitionState#MutableTransitionState(S) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialState in androidx.compose.animation.core.MutableTransitionState(S initialState)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animate(androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, T, androidx.compose.animation.core.AnimationSpec<T>, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity, androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg7)
+InvalidNullConversion: androidx.compose.animation.core.SuspendAnimationKt#animateTo(androidx.compose.animation.core.AnimationState<T,V>, T, androidx.compose.animation.core.AnimationSpec<T>, boolean, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit>, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.SuspendAnimationKt.animateTo(androidx.compose.animation.core.AnimationState<T,V> arg1, T targetValue, androidx.compose.animation.core.AnimationSpec<T> animationSpec, boolean sequentialAnimation, kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit> arg6)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.TargetBasedAnimation#TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, T, T, V) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, V initialVelocityVector)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter arg1 in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.Transition.Segment#isTransitioningTo(S, S) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.Transition.Segment.isTransitioningTo(S arg1, S targetState)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T, T, String) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialState in androidx.compose.animation.core.TransitionKt.createChildTransitionInternal(androidx.compose.animation.core.Transition<S> arg1, T initialState, T targetState, String childLabel)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T, T, String) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.TransitionKt.createChildTransitionInternal(androidx.compose.animation.core.Transition<S> arg1, T initialState, T targetState, String childLabel)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T, T, androidx.compose.animation.core.FiniteAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, String) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.animation.core.TransitionKt.createTransitionAnimation(androidx.compose.animation.core.Transition<S> arg1, T initialValue, T targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T, T, androidx.compose.animation.core.FiniteAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V>, String) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetValue in androidx.compose.animation.core.TransitionKt.createTransitionAnimation(androidx.compose.animation.core.Transition<S> arg1, T initialValue, T targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label)
+InvalidNullConversion: androidx.compose.animation.core.TransitionKt#updateTransition(T, String) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.core.TransitionKt.updateTransition(T targetState, String label)
diff --git a/compose/animation/animation-core/api/restricted_current.txt b/compose/animation/animation-core/api/restricted_current.txt
index 47a6b51..fa302aa 100644
--- a/compose/animation/animation-core/api/restricted_current.txt
+++ b/compose/animation/animation-core/api/restricted_current.txt
@@ -2,27 +2,27 @@
package androidx.compose.animation.core {
public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
- ctor public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
- ctor @Deprecated public Animatable(T? initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
- method public suspend Object? animateDecay(T? initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
- method public suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+ ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+ ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+ method public suspend Object? animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+ method public suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
method public androidx.compose.runtime.State<T> asState();
method public String getLabel();
method public T? getLowerBound();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
method public T? getUpperBound();
method public T! getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
- method public suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? stop(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public void updateBounds(optional T? lowerBound, optional T? upperBound);
property public final boolean isRunning;
property public final String label;
property public final T? lowerBound;
- property public final T! targetValue;
+ property public final T targetValue;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
property public final T? upperBound;
property public final T! value;
@@ -51,21 +51,21 @@
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends androidx.compose.ui.geometry.Rect> animateRectAsState(androidx.compose.ui.geometry.Rect targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Rect> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Rect,? extends kotlin.Unit>? finishedListener);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,kotlin.Unit>? finishedListener);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,? extends kotlin.Unit>? finishedListener);
- method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
- method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValueAsState(T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>? finishedListener);
+ method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>? finishedListener);
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface Animation<T, V extends androidx.compose.animation.core.AnimationVector> {
method public long getDurationNanos();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public default boolean isFinishedFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public abstract long durationNanos;
property public abstract boolean isInfinite;
- property public abstract T! targetValue;
+ property public abstract T targetValue;
property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -84,8 +84,8 @@
public final class AnimationKt {
method public static androidx.compose.animation.core.DecayAnimation<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> DecayAnimation(androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, float initialValue, optional float initialVelocity);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, T? initialVelocity);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> T! getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> T getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
}
public final class AnimationResult<T, V extends androidx.compose.animation.core.AnimationVector> {
@@ -101,9 +101,9 @@
method public long getFinishedTimeNanos();
method public long getLastFrameTimeNanos();
method public long getStartTimeNanos();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
@@ -112,9 +112,9 @@
property public final boolean isRunning;
property public final long lastFrameTimeNanos;
property public final long startTimeNanos;
- property public final T! targetValue;
+ property public final T targetValue;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public final T! value;
+ property public final T value;
property public final T! velocity;
property public final V velocityVector;
}
@@ -135,11 +135,11 @@
}
public final class AnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
- ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
method public long getFinishedTimeNanos();
method public long getLastFrameTimeNanos();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
method public T! getVelocity();
method public V getVelocityVector();
method public boolean isRunning();
@@ -147,17 +147,17 @@
property public final boolean isRunning;
property public final long lastFrameTimeNanos;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
property public final T! velocity;
property public final V velocityVector;
}
public final class AnimationStateKt {
method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> AnimationState(float initialValue, optional float initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T? value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> copy(androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D>, optional float value, optional float velocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T? value);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T value);
method public static boolean isFinished(androidx.compose.animation.core.AnimationState<?,?>);
}
@@ -213,22 +213,22 @@
}
public final class DecayAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
- ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
- ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, V initialVelocityVector);
- ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+ ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+ ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+ ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
method public long getDurationNanos();
- method public T! getInitialValue();
+ method public T getInitialValue();
method public V getInitialVelocityVector();
- method public T! getTargetValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public long durationNanos;
- property public final T! initialValue;
+ property public final T initialValue;
property public final V initialVelocityVector;
property public boolean isInfinite;
- property public T! targetValue;
+ property public T targetValue;
property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -237,7 +237,7 @@
}
public final class DecayAnimationSpecKt {
- method public static <T, V extends androidx.compose.animation.core.AnimationVector> T! calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? initialVelocity);
+ method public static <T, V extends androidx.compose.animation.core.AnimationVector> T calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
method public static float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float initialVelocity);
method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> exponentialDecay(optional float frictionMultiplier, optional float absVelocityThreshold);
method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> generateDecayAnimationSpec(androidx.compose.animation.core.FloatDecayAnimationSpec);
@@ -415,19 +415,19 @@
method public androidx.compose.animation.core.AnimationSpec<T> getAnimationSpec();
method public String getLabel();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
property public final androidx.compose.animation.core.AnimationSpec<T> animationSpec;
property public final String label;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
}
public final class InfiniteTransitionKt {
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec, optional String label);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<? extends java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec);
- method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T? initialValue, T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
- method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValue(androidx.compose.animation.core.InfiniteTransition, T? initialValue, T? targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
+ method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<? extends T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
method @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
}
@@ -444,8 +444,8 @@
public static final class KeyframesSpec.KeyframesSpecConfig<T> {
ctor public KeyframesSpec.KeyframesSpecConfig();
- method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T?, int timeStamp);
- method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T?, float fraction);
+ method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T, int timeStamp);
+ method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T, float fraction);
method public int getDelayMillis();
method public int getDurationMillis();
method public void setDelayMillis(int);
@@ -456,14 +456,14 @@
}
public final class MutableTransitionState<S> {
- ctor public MutableTransitionState(S? initialState);
- method public S! getCurrentState();
- method public S! getTargetState();
+ ctor public MutableTransitionState(S initialState);
+ method public S getCurrentState();
+ method public S getTargetState();
method public boolean isIdle();
method public void setTargetState(S!);
- property public final S! currentState;
+ property public final S currentState;
property public final boolean isIdle;
- property public final S! targetState;
+ property public final S targetState;
}
public enum RepeatMode {
@@ -543,25 +543,25 @@
public final class SuspendAnimationKt {
method public static suspend Object? animate(float initialValue, float targetValue, optional float initialVelocity, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public static suspend Object? animateDecay(float initialValue, float initialVelocity, androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateDecay(androidx.compose.animation.core.AnimationState<T,V>, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T? targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
public final class TargetBasedAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
- ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T? initialValue, T? targetValue, optional V? initialVelocityVector);
+ ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional V? initialVelocityVector);
method public long getDurationNanos();
- method public T! getInitialValue();
- method public T! getTargetValue();
+ method public T getInitialValue();
+ method public T getTargetValue();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValueFromNanos(long playTimeNanos);
+ method public T getValueFromNanos(long playTimeNanos);
method public V getVelocityVectorFromNanos(long playTimeNanos);
method public boolean isInfinite();
property public long durationNanos;
- property public final T! initialValue;
+ property public final T initialValue;
property public boolean isInfinite;
- property public T! targetValue;
+ property public T targetValue;
property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
}
@@ -571,7 +571,7 @@
method public S! getCurrentState();
method public String? getLabel();
method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
- method public S! getTargetState();
+ method public S getTargetState();
method public long getTotalDurationNanos();
method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
method public boolean isRunning();
@@ -580,17 +580,17 @@
property public final boolean isRunning;
property public final String? label;
property public final androidx.compose.animation.core.Transition.Segment<S> segment;
- property public final S! targetState;
+ property public final S targetState;
property public final long totalDurationNanos;
property public final java.util.List<androidx.compose.animation.core.Transition<?>> transitions;
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface Transition.Segment<S> {
- method public S! getInitialState();
- method public S! getTargetState();
- method public default infix boolean isTransitioningTo(S?, S? targetState);
- property public abstract S! initialState;
- property public abstract S! targetState;
+ method public S getInitialState();
+ method public S getTargetState();
+ method public default infix boolean isTransitioningTo(S, S targetState);
+ property public abstract S initialState;
+ property public abstract S targetState;
}
@androidx.compose.runtime.Stable public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
@@ -598,12 +598,12 @@
method public androidx.compose.animation.core.FiniteAnimationSpec<T> getAnimationSpec();
method public String getLabel();
method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
- method public T! getValue();
+ method public T getValue();
property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
property public final androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec;
property public final String label;
property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
- property public T! value;
+ property public T value;
}
public final class TransitionKt {
@@ -616,9 +616,9 @@
method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRect(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Rect>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Rect> targetValueByState);
method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Size>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Size> targetValueByState);
method @androidx.compose.runtime.Composable public static inline <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.Transition<S>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<T>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> targetValueByState);
- method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static <S, T> androidx.compose.animation.core.Transition<T> createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T? initialState, T? targetState, String childLabel);
- method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T? initialValue, T? targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T? targetState, optional String? label);
+ method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static <S, T> androidx.compose.animation.core.Transition<T> createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T initialState, T targetState, String childLabel);
+ method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T initialValue, T targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional String? label);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(androidx.compose.animation.core.MutableTransitionState<T> transitionState, optional String? label);
}
diff --git a/compose/animation/animation/api/api_lint.ignore b/compose/animation/animation/api/api_lint.ignore
new file mode 100644
index 0000000..b6ae3c2
--- /dev/null
+++ b/compose/animation/animation/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field SizeTransform.clip:
+ Invalid name for boolean property `clip`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/animation/animation/api/current.ignore b/compose/animation/animation/api/current.ignore
index a02af1a..029cfad 100644
--- a/compose/animation/animation/api/current.ignore
+++ b/compose/animation/animation/api/current.ignore
@@ -1,3 +1,9 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content)
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content)
+
+
RemovedDeprecatedMethod: androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt#splineBasedDecayDeprecated(androidx.compose.ui.unit.Density):
Removed deprecated method androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt.splineBasedDecayDeprecated(androidx.compose.ui.unit.Density)
diff --git a/compose/animation/animation/api/current.txt b/compose/animation/animation/api/current.txt
index 21b8968..c0d2f31 100644
--- a/compose/animation/animation/api/current.txt
+++ b/compose/animation/animation/api/current.txt
@@ -6,7 +6,7 @@
}
public final class AnimatedContentKt {
- method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S? targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(androidx.compose.animation.core.Transition<S>, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
method public static androidx.compose.animation.SizeTransform SizeTransform(optional boolean clip, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> sizeAnimationSpec);
method public static infix androidx.compose.animation.ContentTransform togetherWith(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
@@ -74,8 +74,8 @@
}
public final class CrossfadeKt {
- method @androidx.compose.runtime.Composable public static <T> void Crossfade(T? targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
- method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T? targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content);
}
public final class EnterExitTransitionKt {
diff --git a/compose/animation/animation/api/public_plus_experimental_current.txt b/compose/animation/animation/api/public_plus_experimental_current.txt
index 3c78e83..37c2eb3 100644
--- a/compose/animation/animation/api/public_plus_experimental_current.txt
+++ b/compose/animation/animation/api/public_plus_experimental_current.txt
@@ -6,7 +6,7 @@
}
public final class AnimatedContentKt {
- method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S? targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(androidx.compose.animation.core.Transition<S>, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
method public static androidx.compose.animation.SizeTransform SizeTransform(optional boolean clip, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> sizeAnimationSpec);
method public static infix androidx.compose.animation.ContentTransform togetherWith(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
@@ -80,9 +80,9 @@
}
public final class CrossfadeKt {
- method @androidx.compose.runtime.Composable public static <T> void Crossfade(T? targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void Crossfade(androidx.compose.animation.core.Transition<T>, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,?> contentKey, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
- method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T? targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content);
}
@androidx.compose.animation.ExperimentalAnimationApi public enum EnterExitState {
diff --git a/compose/animation/animation/api/restricted_current.ignore b/compose/animation/animation/api/restricted_current.ignore
index a02af1a..029cfad 100644
--- a/compose/animation/animation/api/restricted_current.ignore
+++ b/compose/animation/animation/api/restricted_current.ignore
@@ -1,3 +1,9 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, String, kotlin.jvm.functions.Function1<? super T,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content)
+InvalidNullConversion: androidx.compose.animation.CrossfadeKt#Crossfade(T, androidx.compose.ui.Modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter targetState in androidx.compose.animation.CrossfadeKt.Crossfade(T targetState, androidx.compose.ui.Modifier modifier, androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content)
+
+
RemovedDeprecatedMethod: androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt#splineBasedDecayDeprecated(androidx.compose.ui.unit.Density):
Removed deprecated method androidx.compose.animation.SplineBasedFloatDecayAnimationSpec_androidKt.splineBasedDecayDeprecated(androidx.compose.ui.unit.Density)
diff --git a/compose/animation/animation/api/restricted_current.txt b/compose/animation/animation/api/restricted_current.txt
index 21b8968..c0d2f31 100644
--- a/compose/animation/animation/api/restricted_current.txt
+++ b/compose/animation/animation/api/restricted_current.txt
@@ -6,7 +6,7 @@
}
public final class AnimatedContentKt {
- method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S? targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(androidx.compose.animation.core.Transition<S>, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
method public static androidx.compose.animation.SizeTransform SizeTransform(optional boolean clip, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> sizeAnimationSpec);
method public static infix androidx.compose.animation.ContentTransform togetherWith(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
@@ -74,8 +74,8 @@
}
public final class CrossfadeKt {
- method @androidx.compose.runtime.Composable public static <T> void Crossfade(T? targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
- method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T? targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+ method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> content);
}
public final class EnterExitTransitionKt {
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt
index a8c89ec..d3756c6 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithFlowRowDemo.kt
@@ -18,9 +18,10 @@
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ExperimentalLayoutApi
+import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@@ -39,15 +40,10 @@
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.LookaheadScope
-import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
-import kotlin.math.max
-@OptIn(ExperimentalComposeUiApi::class)
+@OptIn(ExperimentalComposeUiApi::class, ExperimentalLayoutApi::class)
@Composable
fun LookaheadWithFlowRowDemo() {
Column(
@@ -67,7 +63,7 @@
) {
Text("LookaheadScope + Modifier.animateBounds")
LookaheadScope {
- MyFlowRow(
+ FlowRow(
modifier = Modifier
.height(200.dp)
.fillMaxWidth()
@@ -110,7 +106,7 @@
.padding(10.dp)
) {
Text("Animating Width")
- MyFlowRow(
+ FlowRow(
modifier = Modifier
.height(200.dp)
.fillMaxWidth()
@@ -139,102 +135,6 @@
}
}
-@Composable
-internal fun MyFlowRow(
- modifier: Modifier = Modifier,
- mainAxisSpacing: Dp = 20.dp,
- crossAxisSpacing: Dp = 20.dp,
- content: @Composable () -> Unit
-) {
- Layout(modifier = modifier, content = content) { measurables, constraints ->
- val sequences = mutableListOf<List<Placeable>>()
- val crossAxisSizes = mutableListOf<Int>()
- val crossAxisPositions = mutableListOf<Int>()
-
- var mainAxisSpace = 0
- var crossAxisSpace = 0
-
- val currentSequence = mutableListOf<Placeable>()
- var currentMainAxisSize = 0
- var currentCrossAxisSize = 0
-
- // Return whether the placeable can be added to the current sequence.
- fun canAddToCurrentSequence(placeable: Placeable) =
- currentSequence.isEmpty() || currentMainAxisSize + mainAxisSpacing.roundToPx() +
- placeable.width <= constraints.maxWidth
-
- // Store current sequence information and start a new sequence.
- fun startNewSequence() {
- if (sequences.isNotEmpty()) {
- crossAxisSpace += crossAxisSpacing.roundToPx()
- }
- sequences += currentSequence.toList()
- crossAxisSizes += currentCrossAxisSize
- crossAxisPositions += crossAxisSpace
-
- crossAxisSpace += currentCrossAxisSize
- mainAxisSpace = max(mainAxisSpace, currentMainAxisSize)
-
- currentSequence.clear()
- currentMainAxisSize = 0
- currentCrossAxisSize = 0
- }
-
- for (measurable in measurables) {
- // Ask the child for its preferred size.
- val placeable = measurable.measure(constraints)
-
- // Start a new sequence if there is not enough space.
- if (!canAddToCurrentSequence(placeable)) startNewSequence()
-
- // Add the child to the current sequence.
- if (currentSequence.isNotEmpty()) {
- currentMainAxisSize += mainAxisSpacing.roundToPx()
- }
- currentSequence.add(placeable)
- currentMainAxisSize += placeable.width
- currentCrossAxisSize = max(currentCrossAxisSize, placeable.height)
- }
-
- if (currentSequence.isNotEmpty()) startNewSequence()
-
- val mainAxisLayoutSize = max(mainAxisSpace, constraints.minWidth)
-
- val crossAxisLayoutSize = max(crossAxisSpace, constraints.minHeight)
-
- val layoutWidth = mainAxisLayoutSize
-
- val layoutHeight = crossAxisLayoutSize
-
- layout(layoutWidth, layoutHeight) {
- sequences.forEachIndexed { i, placeables ->
- val childrenMainAxisSizes = IntArray(placeables.size) { j ->
- placeables[j].width +
- if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
- }
- val arrangement = Arrangement.Start
- // TODO(soboleva): rtl support
- // Handle vertical direction
- val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
- with(arrangement) {
- arrange(
- mainAxisLayoutSize,
- childrenMainAxisSizes,
- LayoutDirection.Ltr,
- mainAxisPositions
- )
- }
- placeables.forEachIndexed { j, placeable ->
- placeable.place(
- x = mainAxisPositions[j],
- y = crossAxisPositions[i]
- )
- }
- }
- }
- }
-}
-
private val colors = listOf(
Color(0xffff6f69),
Color(0xffffcc5c),
diff --git a/compose/foundation/foundation-layout/api/current.txt b/compose/foundation/foundation-layout/api/current.txt
index c8e0c04..4339957 100644
--- a/compose/foundation/foundation-layout/api/current.txt
+++ b/compose/foundation/foundation-layout/api/current.txt
@@ -111,6 +111,12 @@
method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
}
+ @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
+ }
+
+ @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
+ }
+
public final class IntrinsicKt {
method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
diff --git a/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt b/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
index 57c57c0..3e7c323 100644
--- a/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation-layout/api/public_plus_experimental_current.txt
@@ -114,9 +114,15 @@
@kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalLayoutApi {
}
+ @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
+ }
+
public final class FlowLayoutKt {
- method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional int maxItemsInEachColumn, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
- method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional int maxItemsInEachRow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional int maxItemsInEachColumn, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowColumnScope,kotlin.Unit> content);
+ method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional int maxItemsInEachRow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowRowScope,kotlin.Unit> content);
+ }
+
+ @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
}
public final class IntrinsicKt {
diff --git a/compose/foundation/foundation-layout/api/restricted_current.txt b/compose/foundation/foundation-layout/api/restricted_current.txt
index 03cdfb3..2b75f19 100644
--- a/compose/foundation/foundation-layout/api/restricted_current.txt
+++ b/compose/foundation/foundation-layout/api/restricted_current.txt
@@ -114,11 +114,17 @@
method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
}
+ @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
+ }
+
public final class FlowLayoutKt {
method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy columnMeasurementHelper(androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, int maxItemsInMainAxis);
method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy rowMeasurementHelper(androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, int maxItemsInMainAxis);
}
+ @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
+ }
+
public final class IntrinsicKt {
method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
index 39c2067..8142e08 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/FlowRowColumnTest.kt
@@ -2482,4 +2482,60 @@
rule.waitForIdle()
Truth.assertThat(height).isEqualTo(180)
}
+
+ @Test
+ fun testFlowRow_constrainsOverflow() {
+ var width = 0
+ rule.setContent {
+ with(LocalDensity.current) {
+ Box(Modifier.size(200.toDp())) {
+ FlowRow(
+ Modifier
+ .fillMaxWidth(1f)
+ .onSizeChanged {
+ width = it.width
+ },
+ verticalArrangement = Arrangement.spacedBy(20.toDp()),
+ ) {
+ repeat(2) {
+ Box(
+ Modifier
+ .size(250.toDp())
+ )
+ }
+ }
+ }
+ }
+ }
+ rule.waitForIdle()
+ Truth.assertThat(width).isEqualTo(200)
+ }
+
+ @Test
+ fun testFlowColumn_constrainsOverflow() {
+ var height = 0
+ rule.setContent {
+ with(LocalDensity.current) {
+ Box(Modifier.size(200.toDp())) {
+ FlowColumn(
+ Modifier
+ .fillMaxWidth(1f)
+ .onSizeChanged {
+ height = it.height
+ },
+ horizontalArrangement = Arrangement.spacedBy(20.toDp()),
+ ) {
+ repeat(2) {
+ Box(
+ Modifier
+ .size(250.toDp())
+ )
+ }
+ }
+ }
+ }
+ }
+ rule.waitForIdle()
+ Truth.assertThat(height).isEqualTo(200)
+ }
}
\ No newline at end of file
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
index 9ec9beb..5d58064 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
@@ -1,6 +1,7 @@
package androidx.compose.foundation.layout
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
import androidx.compose.runtime.collection.MutableVector
import androidx.compose.runtime.collection.mutableVectorOf
import androidx.compose.runtime.remember
@@ -56,7 +57,7 @@
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
maxItemsInEachRow: Int = Int.MAX_VALUE,
- content: @Composable RowScope.() -> Unit
+ content: @Composable FlowRowScope.() -> Unit
) {
val measurePolicy = rowMeasurementHelper(
horizontalArrangement,
@@ -64,7 +65,7 @@
maxItemsInEachRow
)
Layout(
- content = { RowScopeInstance.content() },
+ content = { FlowRowScopeInstance.content() },
measurePolicy = measurePolicy,
modifier = modifier
)
@@ -106,7 +107,7 @@
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
maxItemsInEachColumn: Int = Int.MAX_VALUE,
- content: @Composable ColumnScope.() -> Unit
+ content: @Composable FlowColumnScope.() -> Unit
) {
val measurePolicy = columnMeasurementHelper(
verticalArrangement,
@@ -114,12 +115,32 @@
maxItemsInEachColumn
)
Layout(
- content = { ColumnScopeInstance.content() },
+ content = { FlowColumnScopeInstance.content() },
measurePolicy = measurePolicy,
modifier = modifier
)
}
+/**
+ * Scope for the children of [FlowRow].
+ */
+@LayoutScopeMarker
+@Immutable
+@JvmDefaultWithCompatibility
+interface FlowRowScope : RowScope
+
+/**
+ * Scope for the children of [FlowColumn].
+ */
+@LayoutScopeMarker
+@Immutable
+@JvmDefaultWithCompatibility
+interface FlowColumnScope : ColumnScope
+
+internal object FlowRowScopeInstance : RowScope by RowScopeInstance, FlowRowScope
+
+internal object FlowColumnScopeInstance : ColumnScope by ColumnScopeInstance, FlowColumnScope
+
private fun getVerticalArrangement(verticalArrangement: Arrangement.Vertical):
(Int, IntArray, LayoutDirection, Density, IntArray) -> Unit =
{ totalSize: Int, size: IntArray, _, density: Density, outPosition: IntArray ->
@@ -624,6 +645,7 @@
leftOver - (nextSize ?: 0) < 0
) {
mainAxisTotalSize = maxOf(mainAxisTotalSize, currentLineMainAxisSize)
+ mainAxisTotalSize = minOf(mainAxisTotalSize, mainAxisMax)
currentLineMainAxisSize = 0
leftOver = mainAxisMax
startBreakLineIndex = index + 1
diff --git a/compose/foundation/foundation/api/api_lint.ignore b/compose/foundation/foundation/api/api_lint.ignore
new file mode 100644
index 0000000..0e31469
--- /dev/null
+++ b/compose/foundation/foundation/api/api_lint.ignore
@@ -0,0 +1,33 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.compose.foundation.ScrollState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.ScrollState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.gestures.ScrollableState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.gestures.ScrollableState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.LazyListState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.LazyListState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.grid.LazyGridState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.grid.LazyGridState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.pager.PagerState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.pager.PagerState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.foundation.text2.input.TextFieldBufferWithSelection#getHasSelection():
+ Getter for boolean property `hasSelection` is named `getHasSelection` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field KeyboardOptions.autoCorrect:
+ Invalid name for boolean property `autoCorrect`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field LazyGridLayoutInfo.reverseLayout:
+ Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field LazyListLayoutInfo.reverseLayout:
+ Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/foundation/foundation/api/current.ignore b/compose/foundation/foundation/api/current.ignore
new file mode 100644
index 0000000..feba6f7
--- /dev/null
+++ b/compose/foundation/foundation/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.foundation.MutatorMutex#mutateWith(T, androidx.compose.foundation.MutatePriority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?>, kotlin.coroutines.Continuation<? super R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter receiver in androidx.compose.foundation.MutatorMutex.mutateWith(T receiver, androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> arg4)
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index f5e2dc7..2a1b29f 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -91,7 +91,7 @@
@androidx.compose.runtime.Stable public final class MutatorMutex {
ctor public MutatorMutex();
method public suspend <R> Object? mutate(optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
- method public suspend <T, R> Object? mutateWith(T? receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+ method public suspend <T, R> Object? mutateWith(T receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
}
public final class ProgressSemanticsKt {
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index fd47f6e..0ce3cfef 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -156,7 +156,7 @@
@androidx.compose.runtime.Stable public final class MutatorMutex {
ctor public MutatorMutex();
method public suspend <R> Object? mutate(optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
- method public suspend <T, R> Object? mutateWith(T? receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+ method public suspend <T, R> Object? mutateWith(T receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
}
@androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class OverscrollConfiguration {
@@ -746,10 +746,10 @@
public static final class IntervalList.Interval<T> {
method public int getSize();
method public int getStartIndex();
- method public T! getValue();
+ method public T getValue();
property public final int size;
property public final int startIndex;
- property public final T! value;
+ property public final T value;
}
@androidx.compose.foundation.ExperimentalFoundationApi public abstract class LazyLayoutIntervalContent<Interval extends androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.Interval> {
@@ -832,7 +832,7 @@
@androidx.compose.foundation.ExperimentalFoundationApi public final class MutableIntervalList<T> implements androidx.compose.foundation.lazy.layout.IntervalList<T> {
ctor public MutableIntervalList();
- method public void addInterval(int size, T? value);
+ method public void addInterval(int size, T value);
method public void forEach(int fromIndex, int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
method public androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
method public int getSize();
diff --git a/compose/foundation/foundation/api/restricted_current.ignore b/compose/foundation/foundation/api/restricted_current.ignore
new file mode 100644
index 0000000..feba6f7
--- /dev/null
+++ b/compose/foundation/foundation/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.foundation.MutatorMutex#mutateWith(T, androidx.compose.foundation.MutatePriority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?>, kotlin.coroutines.Continuation<? super R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter receiver in androidx.compose.foundation.MutatorMutex.mutateWith(T receiver, androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R> arg4)
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index f5e2dc7..2a1b29f 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -91,7 +91,7 @@
@androidx.compose.runtime.Stable public final class MutatorMutex {
ctor public MutatorMutex();
method public suspend <R> Object? mutate(optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
- method public suspend <T, R> Object? mutateWith(T? receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+ method public suspend <T, R> Object? mutateWith(T receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
}
public final class ProgressSemanticsKt {
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
index f4f50f1..b80442a 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
@@ -1068,7 +1068,7 @@
.weight(1f), reverseLayout = reverse) {
items(items, key = { it }) { item ->
val selected = selectedIndexes.getOrDefault(item, false)
- val modifier = if (selected) Modifier.animateItemPlacement() else Modifier
+ val modifier = Modifier.animateItemPlacement()
var height by remember { mutableStateOf(40.dp) }
Row(
modifier
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
index 809d77a..61ce9f7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
@@ -72,15 +72,17 @@
@get:Rule
val rule = createComposeRule()
- private val itemSize: Float = 50f
+ // the numbers should be divisible by 8 to avoid the rounding issues as we run 4 or 8 frames
+ // of the animation.
+ private val itemSize: Float = 40f
private var itemSizeDp: Dp = Dp.Infinity
- private val itemSize2: Float = 30f
+ private val itemSize2: Float = 24f
private var itemSize2Dp: Dp = Dp.Infinity
- private val itemSize3: Float = 20f
+ private val itemSize3: Float = 16f
private var itemSize3Dp: Dp = Dp.Infinity
private val containerSize: Float = itemSize * 5
private var containerSizeDp: Dp = Dp.Infinity
- private val spacing: Float = 10f
+ private val spacing: Float = 8f
private var spacingDp: Dp = Dp.Infinity
private val itemSizePlusSpacing = itemSize + spacing
private var itemSizePlusSpacingDp = Dp.Infinity
@@ -2085,6 +2087,173 @@
}
}
+ @Test
+ fun scrollIsAffectingItemsMovingWithinViewport() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3))
+ val scrollDelta = spacing
+ rule.setContent {
+ LazyGrid(1, maxSize = itemSizeDp * 2) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(0, 2, 1, 3)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, itemSize),
+ 2 to AxisOffset(0f, itemSize * 2),
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ }
+ assertPositions(
+ 0 to AxisOffset(0f, -scrollDelta),
+ 1 to AxisOffset(0f, itemSize - scrollDelta + itemSize * fraction),
+ 2 to AxisOffset(0f, itemSize * 2 - scrollDelta - itemSize * fraction),
+ fraction = fraction
+ )
+ }
+ }
+
+ @Test
+ fun scrollIsNotAffectingItemMovingToTheBottomOutsideOfBounds() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+ val scrollDelta = spacing
+ val containerSizeDp = itemSizeDp * 2
+ val containerSize = itemSize * 2
+ rule.setContent {
+ LazyGrid(1, maxSize = containerSizeDp) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(0, 4, 2, 3, 1)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, itemSize),
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ }
+ assertPositions(
+ 0 to AxisOffset(0f, -scrollDelta),
+ 1 to AxisOffset(0f, itemSize + (containerSize - itemSize) * fraction),
+ fraction = fraction
+ )
+ }
+ }
+
+ @Test
+ fun scrollIsNotAffectingItemMovingToTheTopOutsideOfBounds() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+ val scrollDelta = -spacing
+ val containerSizeDp = itemSizeDp * 2
+ rule.setContent {
+ LazyGrid(1, maxSize = containerSizeDp, startIndex = 2) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(3, 0, 1, 2, 4)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 2 to AxisOffset(0f, 0f),
+ 3 to AxisOffset(0f, itemSize),
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ }
+ assertPositions(
+ 2 to AxisOffset(0f, -scrollDelta),
+ 3 to AxisOffset(0f, itemSize - (itemSize * 2 * fraction)),
+ fraction = fraction
+ )
+ }
+ }
+
+ @Test
+ fun afterScrollingEnoughToReachNewPositionScrollDeltasStartAffectingPosition() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+ val containerSizeDp = itemSizeDp * 2
+ val scrollDelta = spacing
+ rule.setContent {
+ LazyGrid(1, maxSize = containerSizeDp) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(0, 4, 2, 3, 1)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, itemSize),
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(itemSize * 2) }
+ }
+ assertPositions(
+ 2 to AxisOffset(0f, 0f),
+ 3 to AxisOffset(0f, itemSize),
+ // after the first scroll the new position of item 1 is still not reached
+ // so the target didn't change, we still aim to end right after the bounds
+ 1 to AxisOffset(0f, itemSize),
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ assertPositions(
+ 2 to AxisOffset(0f, 0f - scrollDelta),
+ 3 to AxisOffset(0f, itemSize - scrollDelta),
+ // after the second scroll the item 1 is visible, so we know its new target
+ // position. the animation is now targeting the real end position and now
+ // we are reacting on the scroll deltas
+ 1 to AxisOffset(0f, itemSize - scrollDelta),
+ fraction = fraction
+ )
+ }
+ assertPositions(
+ 2 to AxisOffset(0f, -scrollDelta),
+ 3 to AxisOffset(0f, itemSize - scrollDelta),
+ 1 to AxisOffset(0f, itemSize - scrollDelta + itemSize * fraction),
+ fraction = fraction
+ )
+ }
+ }
+
private fun AxisOffset(crossAxis: Float, mainAxis: Float) =
if (isVertical) Offset(crossAxis, mainAxis) else Offset(mainAxis, crossAxis)
@@ -2224,7 +2393,11 @@
animSpec: FiniteAnimationSpec<IntOffset>? = AnimSpec
) {
Box(
- Modifier
+ if (animSpec != null) {
+ Modifier.animateItemPlacement(animSpec)
+ } else {
+ Modifier
+ }
.then(
if (isVertical) {
Modifier.requiredHeight(size)
@@ -2233,13 +2406,6 @@
}
)
.testTag(tag.toString())
- .then(
- if (animSpec != null) {
- Modifier.animateItemPlacement(animSpec)
- } else {
- Modifier
- }
- )
)
}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
index 6f21f95..fa60831 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
@@ -85,15 +85,17 @@
@get:Rule
val rule = createComposeRule()
- private val itemSize: Float = 50f
+ // the numbers should be divisible by 8 to avoid the rounding issues as we run 4 or 8 frames
+ // of the animation.
+ private val itemSize: Float = 40f
private var itemSizeDp: Dp = Dp.Infinity
- private val itemSize2: Float = 30f
+ private val itemSize2: Float = 24f
private var itemSize2Dp: Dp = Dp.Infinity
- private val itemSize3: Float = 20f
+ private val itemSize3: Float = 16f
private var itemSize3Dp: Dp = Dp.Infinity
private val containerSize: Float = itemSize * 5
private var containerSizeDp: Dp = Dp.Infinity
- private val spacing: Float = 10f
+ private val spacing: Float = 8f
private var spacingDp: Dp = Dp.Infinity
private val itemSizePlusSpacing = itemSize + spacing
private var itemSizePlusSpacingDp = Dp.Infinity
@@ -1534,6 +1536,173 @@
}
}
+ @Test
+ fun scrollIsAffectingItemsMovingWithinViewport() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3))
+ val scrollDelta = spacing
+ rule.setContent {
+ LazyList(maxSize = itemSizeDp * 2) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(0, 2, 1, 3)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to 0f,
+ 1 to itemSize,
+ 2 to itemSize * 2,
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ }
+ assertPositions(
+ 0 to -scrollDelta,
+ 1 to itemSize - scrollDelta + itemSize * fraction,
+ 2 to itemSize * 2 - scrollDelta - itemSize * fraction,
+ fraction = fraction
+ )
+ }
+ }
+
+ @Test
+ fun scrollIsNotAffectingItemMovingToTheBottomOutsideOfBounds() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+ val scrollDelta = spacing
+ val containerSizeDp = itemSizeDp * 2
+ val containerSize = itemSize * 2
+ rule.setContent {
+ LazyList(maxSize = containerSizeDp) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(0, 4, 2, 3, 1)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to 0f,
+ 1 to itemSize,
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ }
+ assertPositions(
+ 0 to -scrollDelta,
+ 1 to itemSize + (containerSize - itemSize) * fraction,
+ fraction = fraction
+ )
+ }
+ }
+
+ @Test
+ fun scrollIsNotAffectingItemMovingToTheTopOutsideOfBounds() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+ val scrollDelta = -spacing
+ val containerSizeDp = itemSizeDp * 2
+ rule.setContent {
+ LazyList(maxSize = containerSizeDp, startIndex = 2) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(3, 0, 1, 2, 4)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 2 to 0f,
+ 3 to itemSize,
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ }
+ assertPositions(
+ 2 to -scrollDelta,
+ 3 to itemSize - (itemSize * 2 * fraction),
+ fraction = fraction
+ )
+ }
+ }
+
+ @Test
+ fun afterScrollingEnoughToReachNewPositionScrollDeltasStartAffectingPosition() {
+ var list by mutableStateOf(listOf(0, 1, 2, 3, 4))
+ val containerSizeDp = itemSizeDp * 2
+ val scrollDelta = spacing
+ rule.setContent {
+ LazyList(maxSize = containerSizeDp) {
+ items(list, key = { it }) {
+ Item(it)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ list = listOf(0, 4, 2, 3, 1)
+ }
+
+ onAnimationFrame { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to 0f,
+ 1 to itemSize,
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(itemSize * 2) }
+ }
+ assertPositions(
+ 2 to 0f,
+ 3 to itemSize,
+ // after the first scroll the new position of item 1 is still not reached
+ // so the target didn't change, we still aim to end right after the bounds
+ 1 to itemSize,
+ fraction = fraction
+ )
+ rule.runOnUiThread {
+ runBlocking { state.scrollBy(scrollDelta) }
+ }
+ assertPositions(
+ 2 to 0f - scrollDelta,
+ 3 to itemSize - scrollDelta,
+ // after the second scroll the item 1 is visible, so we know its new target
+ // position. the animation is now targeting the real end position and now
+ // we are reacting on the scroll deltas
+ 1 to itemSize - scrollDelta,
+ fraction = fraction
+ )
+ }
+ assertPositions(
+ 2 to -scrollDelta,
+ 3 to itemSize - scrollDelta,
+ 1 to itemSize - scrollDelta + itemSize * fraction,
+ fraction = fraction
+ )
+ }
+ }
+
private fun assertPositions(
vararg expected: Pair<Any, Float>,
crossAxis: List<Pair<Any, Float>>? = null,
@@ -1693,26 +1862,24 @@
crossAxisSize: Dp = size,
animSpec: FiniteAnimationSpec<IntOffset>? = AnimSpec
) {
- Box(Modifier
- .then(
- if (isVertical) {
- Modifier
- .requiredHeight(size)
- .requiredWidth(crossAxisSize)
- } else {
- Modifier
- .requiredWidth(size)
- .requiredHeight(crossAxisSize)
- }
- )
- .testTag(tag.toString())
- .then(
- if (animSpec != null) {
- Modifier.animateItemPlacement(animSpec)
- } else {
- Modifier
- }
- )
+ Box(
+ if (animSpec != null) {
+ Modifier.animateItemPlacement(animSpec)
+ } else {
+ Modifier
+ }
+ .then(
+ if (isVertical) {
+ Modifier
+ .requiredHeight(size)
+ .requiredWidth(crossAxisSize)
+ } else {
+ Modifier
+ .requiredWidth(size)
+ .requiredHeight(crossAxisSize)
+ }
+ )
+ .testTag(tag.toString())
)
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
index 6fa0739..ab0b5f5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
@@ -17,7 +17,6 @@
package androidx.compose.foundation
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
@@ -26,8 +25,9 @@
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawOutline
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.InspectorInfo
-import androidx.compose.ui.platform.InspectorValueInfo
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.LayoutDirection
@@ -42,18 +42,22 @@
fun Modifier.background(
color: Color,
shape: Shape = RectangleShape
-) = this.then(
- Background(
- color = color,
- shape = shape,
- inspectorInfo = debugInspectorInfo {
- name = "background"
- value = color
- properties["color"] = color
- properties["shape"] = shape
- }
+): Modifier {
+ val alpha = 1.0f // for solid colors
+ return this.then(
+ BackgroundElement(
+ color = color,
+ shape = shape,
+ alpha = alpha,
+ inspectorInfo = debugInspectorInfo {
+ name = "background"
+ value = color
+ properties["color"] = color
+ properties["shape"] = shape
+ }
+ )
)
-)
+}
/**
* Draws [shape] with [brush] behind the content.
@@ -71,7 +75,7 @@
/*@FloatRange(from = 0.0, to = 1.0)*/
alpha: Float = 1.0f
) = this.then(
- Background(
+ BackgroundElement(
brush = brush,
alpha = alpha,
shape = shape,
@@ -84,13 +88,57 @@
)
)
-private class Background constructor(
+private class BackgroundElement(
private val color: Color? = null,
private val brush: Brush? = null,
- private val alpha: Float = 1.0f,
+ private val alpha: Float,
private val shape: Shape,
- inspectorInfo: InspectorInfo.() -> Unit
-) : DrawModifier, InspectorValueInfo(inspectorInfo) {
+ private val inspectorInfo: InspectorInfo.() -> Unit
+) : ModifierNodeElement<BackgroundNode>() {
+ override fun create(): BackgroundNode {
+ return BackgroundNode(
+ color,
+ brush,
+ alpha,
+ shape
+ )
+ }
+
+ override fun update(node: BackgroundNode): BackgroundNode {
+ node.color = color
+ node.brush = brush
+ node.alpha = alpha
+ node.shape = shape
+ return node
+ }
+
+ override fun InspectorInfo.inspectableProperties() {
+ inspectorInfo()
+ }
+
+ override fun hashCode(): Int {
+ var result = color?.hashCode() ?: 0
+ result = 31 * result + (brush?.hashCode() ?: 0)
+ result = 31 * result + alpha.hashCode()
+ result = 31 * result + shape.hashCode()
+ return result
+ }
+
+ override fun equals(other: Any?): Boolean {
+ val otherModifier = other as? BackgroundElement ?: return false
+ return color == otherModifier.color &&
+ brush == otherModifier.brush &&
+ alpha == otherModifier.alpha &&
+ shape == otherModifier.shape
+ }
+}
+
+private class BackgroundNode(
+ var color: Color?,
+ var brush: Brush?,
+ var alpha: Float,
+ var shape: Shape,
+) : DrawModifierNode, Modifier.Node() {
// naive cache outline calculation if size is the same
private var lastSize: Size? = null
@@ -119,29 +167,10 @@
} else {
shape.createOutline(size, layoutDirection, this)
}
- color?.let { drawOutline(outline, color = color) }
- brush?.let { drawOutline(outline, brush = brush, alpha = alpha) }
+ color?.let { drawOutline(outline, color = it) }
+ brush?.let { drawOutline(outline, brush = it, alpha = alpha) }
lastOutline = outline
lastSize = size
lastLayoutDirection = layoutDirection
}
-
- override fun hashCode(): Int {
- var result = color?.hashCode() ?: 0
- result = 31 * result + (brush?.hashCode() ?: 0)
- result = 31 * result + alpha.hashCode()
- result = 31 * result + shape.hashCode()
- return result
- }
-
- override fun equals(other: Any?): Boolean {
- val otherModifier = other as? Background ?: return false
- return color == otherModifier.color &&
- brush == otherModifier.brush &&
- alpha == otherModifier.alpha &&
- shape == otherModifier.shape
- }
-
- override fun toString(): String =
- "Background(color=$color, brush=$brush, alpha = $alpha, shape=$shape)"
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
index 5d4cbcf..ff2dc1a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScopeImpl.kt
@@ -18,6 +18,7 @@
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
@@ -25,6 +26,7 @@
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.ParentDataModifierNode
@@ -156,10 +158,11 @@
private class AnimateItemPlacementElement(
val animationSpec: FiniteAnimationSpec<IntOffset>
) : ModifierNodeElement<AnimateItemPlacementNode>() {
+
override fun create(): AnimateItemPlacementNode = AnimateItemPlacementNode(animationSpec)
override fun update(node: AnimateItemPlacementNode): AnimateItemPlacementNode = node.also {
- it.animationSpec = animationSpec
+ it.delegatingNode.placementAnimationSpec = animationSpec
}
override fun equals(other: Any?): Boolean {
@@ -179,7 +182,10 @@
}
private class AnimateItemPlacementNode(
- var animationSpec: FiniteAnimationSpec<IntOffset>
-) : Modifier.Node(), ParentDataModifierNode {
- override fun Density.modifyParentData(parentData: Any?): Any = animationSpec
+ animationSpec: FiniteAnimationSpec<IntOffset>
+) : DelegatingNode(), ParentDataModifierNode {
+
+ val delegatingNode = delegated { LazyLayoutAnimateItemModifierNode(animationSpec) }
+
+ override fun Density.modifyParentData(parentData: Any?): Any = delegatingNode
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index 8f6ed38..e606387 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -29,11 +29,11 @@
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.lazy.layout.LazyLayout
import androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope
+import androidx.compose.foundation.lazy.layout.findIndexByKey
import androidx.compose.foundation.lazy.layout.lazyLayoutSemantics
import androidx.compose.foundation.overscroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -44,6 +44,8 @@
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.constrainWidth
import androidx.compose.ui.unit.offset
+import androidx.compose.ui.util.fastForEach
+import kotlin.math.min
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -79,11 +81,6 @@
val semanticState = rememberLazyListSemanticState(state, isVertical)
val beyondBoundsInfo = remember { LazyListBeyondBoundsInfo() }
- val scope = rememberCoroutineScope()
- val placementAnimator = remember(state, isVertical) {
- LazyListItemPlacementAnimator(scope, isVertical)
- }
- state.placementAnimator = placementAnimator
val measurePolicy = rememberLazyListMeasurePolicy(
itemProvider,
@@ -96,8 +93,7 @@
horizontalAlignment,
verticalAlignment,
horizontalArrangement,
- verticalArrangement,
- placementAnimator,
+ verticalArrangement
)
ScrollPositionUpdater(itemProvider, state)
@@ -116,7 +112,13 @@
reverseScrolling = reverseLayout
)
.clipScrollableContainer(orientation)
- .lazyListBeyondBoundsModifier(state, beyondBoundsInfo, reverseLayout, orientation)
+ .lazyListBeyondBoundsModifier(
+ state,
+ beyondBoundsInfo,
+ beyondBoundsItemCount,
+ reverseLayout,
+ orientation
+ )
.overscroll(overscrollEffect)
.scrollable(
orientation = orientation,
@@ -174,8 +176,6 @@
horizontalArrangement: Arrangement.Horizontal? = null,
/** The vertical arrangement for items. Required when isVertical is true */
verticalArrangement: Arrangement.Vertical? = null,
- /** Item placement animator. Should be notified with the measuring result */
- placementAnimator: LazyListItemPlacementAnimator
) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
state,
beyondBoundsInfo,
@@ -185,8 +185,7 @@
horizontalAlignment,
verticalAlignment,
horizontalArrangement,
- verticalArrangement,
- placementAnimator
+ verticalArrangement
) {
{ containerConstraints ->
checkScrollableContainerConstraints(
@@ -284,8 +283,7 @@
afterContentPadding = afterContentPadding,
spacing = spacing,
visualOffset = visualItemOffset,
- key = key,
- placementAnimator = placementAnimator
+ key = key
)
}
state.premeasureConstraints = measuredItemProvider.childConstraints
@@ -297,9 +295,29 @@
firstVisibleScrollOffset = state.firstVisibleItemScrollOffset
}
+ val pinnedItems = if (!beyondBoundsInfo.hasIntervals() && state.pinnedItems.isEmpty()) {
+ emptyList()
+ } else {
+ val pinnedItems = mutableListOf<Int>()
+ val beyondBoundsRange = if (beyondBoundsInfo.hasIntervals()) {
+ beyondBoundsInfo.start..min(beyondBoundsInfo.end, itemsCount - 1)
+ } else {
+ IntRange.EMPTY
+ }
+ state.pinnedItems.fastForEach {
+ val index = itemProvider.findIndexByKey(it.key, it.index)
+ if (index in beyondBoundsRange) return@fastForEach
+ if (index !in 0 until itemsCount) return@fastForEach
+ pinnedItems.add(index)
+ }
+ for (i in beyondBoundsRange) {
+ pinnedItems.add(i)
+ }
+ pinnedItems
+ }
+
measureLazyList(
itemsCount = itemsCount,
- itemProvider = itemProvider,
measuredItemProvider = measuredItemProvider,
mainAxisAvailableSize = mainAxisAvailableSize,
beforeContentPadding = beforeContentPadding,
@@ -315,10 +333,9 @@
horizontalArrangement = horizontalArrangement,
reverseLayout = reverseLayout,
density = this,
- placementAnimator = placementAnimator,
- beyondBoundsInfo = beyondBoundsInfo,
+ placementAnimator = state.placementAnimator,
beyondBoundsItemCount = beyondBoundsItemCount,
- pinnedItems = state.pinnedItems,
+ pinnedItems = pinnedItems,
layout = { width, height, placement ->
layout(
containerConstraints.constrainWidth(width + totalHorizontalPadding),
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
index d84e816..c52f75b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
@@ -33,11 +33,14 @@
internal fun Modifier.lazyListBeyondBoundsModifier(
state: LazyListState,
beyondBoundsInfo: LazyListBeyondBoundsInfo,
+ beyondBoundsItemCount: Int,
reverseLayout: Boolean,
orientation: Orientation
): Modifier {
val layoutDirection = LocalLayoutDirection.current
- val beyondBoundsState = remember(state) { LazyListBeyondBoundsState(state) }
+ val beyondBoundsState = remember(state, beyondBoundsItemCount) {
+ LazyListBeyondBoundsState(state, beyondBoundsItemCount)
+ }
return this then remember(
beyondBoundsState,
beyondBoundsInfo,
@@ -55,7 +58,11 @@
}
}
-internal class LazyListBeyondBoundsState(val state: LazyListState) : BeyondBoundsState {
+internal class LazyListBeyondBoundsState(
+ val state: LazyListState,
+ val beyondBoundsItemCount: Int
+) : BeyondBoundsState {
+
override fun remeasure() {
state.remeasurement?.forceRemeasure()
}
@@ -65,7 +72,10 @@
override val hasVisibleItems: Boolean
get() = state.layoutInfo.visibleItemsInfo.isNotEmpty()
override val firstVisibleIndex: Int
- get() = state.firstVisibleItemIndex
+ get() = maxOf(0, state.firstVisibleItemIndex - beyondBoundsItemCount)
override val lastVisibleIndex: Int
- get() = state.layoutInfo.visibleItemsInfo.last().index
+ get() = minOf(
+ itemCount - 1,
+ state.layoutInfo.visibleItemsInfo.last().index + beyondBoundsItemCount
+ )
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
index 3e94392..6e1f924 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
@@ -16,24 +16,11 @@
package androidx.compose.foundation.lazy
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.Spring
-import androidx.compose.animation.core.SpringSpec
-import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.VisibilityThreshold
-import androidx.compose.animation.core.spring
-import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastForEach
-import androidx.compose.ui.util.fastForEachIndexed
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
/**
* Handles the item placement animations when it is set via [LazyItemScope.animateItemPlacement].
@@ -41,13 +28,9 @@
* This class is responsible for detecting when item position changed, figuring our start/end
* offsets and starting the animations.
*/
-@OptIn(ExperimentalFoundationApi::class)
-internal class LazyListItemPlacementAnimator(
- private val scope: CoroutineScope,
- private val isVertical: Boolean
-) {
- // state containing an animation and all relevant info for each item.
- private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
+internal class LazyListItemPlacementAnimator {
+ // contains the keys of the active items with animation node.
+ private val activeKeys = mutableSetOf<Any>()
// snapshot of the key to index map used for the last measuring.
private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
@@ -72,9 +55,10 @@
layoutWidth: Int,
layoutHeight: Int,
positionedItems: MutableList<LazyListPositionedItem>,
- itemProvider: LazyListMeasuredItemProvider
+ itemProvider: LazyListMeasuredItemProvider,
+ isVertical: Boolean
) {
- if (!positionedItems.fastAny { it.hasAnimations } && keyToItemInfoMap.isEmpty()) {
+ if (!positionedItems.fastAny { it.hasAnimations } && activeKeys.isEmpty()) {
// no animations specified - no work needed
reset()
return
@@ -88,18 +72,21 @@
val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
// the consumed scroll is considered as a delta we don't need to animate
- val notAnimatableDelta = consumedScroll.toOffset()
+ val scrollOffset = if (isVertical) {
+ IntOffset(0, consumedScroll)
+ } else {
+ IntOffset(consumedScroll, 0)
+ }
// first add all items we had in the previous run
- movingAwayKeys.addAll(keyToItemInfoMap.keys)
+ movingAwayKeys.addAll(activeKeys)
// iterate through the items which are visible (without animated offsets)
positionedItems.fastForEach { item ->
// remove items we have in the current one as they are still visible.
movingAwayKeys.remove(item.key)
if (item.hasAnimations) {
- val itemInfo = keyToItemInfoMap[item.key]
- // there is no state associated with this item yet
- if (itemInfo == null) {
+ if (!activeKeys.contains(item.key)) {
+ activeKeys += item.key
val previousIndex = previousKeyToIndexMap[item.key]
if (previousIndex != -1 && item.index != previousIndex) {
if (previousIndex < previousFirstVisibleIndex) {
@@ -109,16 +96,24 @@
movingInFromEndBound.add(item)
}
} else {
- keyToItemInfoMap[item.key] = createItemInfo(item)
+ initializeNode(
+ item,
+ item.getOffset(0).let { if (item.isVertical) it.y else it.x }
+ )
}
} else {
- // this item was visible and is still visible.
- itemInfo.notAnimatableDelta += notAnimatableDelta // apply new scroll delta
- startAnimationsIfNeeded(item, itemInfo)
+ repeat(item.placeablesCount) { placeableIndex ->
+ item.getParentData(placeableIndex).node?.apply {
+ if (rawOffset != LazyLayoutAnimateItemModifierNode.NotInitialized) {
+ rawOffset += scrollOffset
+ }
+ }
+ }
+ startAnimationsIfNeeded(item)
}
} else {
// no animation, clean up if needed
- keyToItemInfoMap.remove(item.key)
+ activeKeys.remove(item.key)
}
}
@@ -127,40 +122,43 @@
movingInFromStartBound.fastForEach { item ->
val mainAxisOffset = 0 - currentMainAxisOffset - item.size
currentMainAxisOffset += item.size
- val itemInfo = createItemInfo(item, mainAxisOffset)
- keyToItemInfoMap[item.key] = itemInfo
- startAnimationsIfNeeded(item, itemInfo)
+ initializeNode(item, mainAxisOffset)
+ startAnimationsIfNeeded(item)
}
currentMainAxisOffset = 0
movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
movingInFromEndBound.fastForEach { item ->
val mainAxisOffset = mainAxisLayoutSize + currentMainAxisOffset
currentMainAxisOffset += item.size
- val itemInfo = createItemInfo(item, mainAxisOffset)
- keyToItemInfoMap[item.key] = itemInfo
- startAnimationsIfNeeded(item, itemInfo)
+ initializeNode(item, mainAxisOffset)
+ startAnimationsIfNeeded(item)
}
movingAwayKeys.forEach { key ->
// found an item which was in our map previously but is not a part of the
// positionedItems now
- val itemInfo = keyToItemInfoMap.getValue(key)
val newIndex = keyToIndexMap[key]
- // whether the animation associated with the item has been finished or not yet started
- val inProgress = itemInfo.placeables.fastAny { it.inProgress }
- if (itemInfo.placeables.isEmpty() ||
- newIndex == -1 ||
- (!inProgress && newIndex == previousKeyToIndexMap[key]) ||
- (!inProgress && !itemInfo.isWithinBounds(mainAxisLayoutSize))
- ) {
- keyToItemInfoMap.remove(key)
+ if (newIndex == -1) {
+ activeKeys.remove(key)
} else {
val item = itemProvider.getAndMeasure(DataIndex(newIndex))
- if (newIndex < firstVisibleIndex) {
- movingAwayToStartBound.add(item)
+ // check if we have any active placement animation on the item
+ var inProgress = false
+ repeat(item.placeablesCount) {
+ if (item.getParentData(it).node?.isAnimationInProgress == true) {
+ inProgress = true
+ return@repeat
+ }
+ }
+ if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+ activeKeys.remove(key)
} else {
- movingAwayToEndBound.add(item)
+ if (newIndex < firstVisibleIndex) {
+ movingAwayToStartBound.add(item)
+ } else {
+ movingAwayToEndBound.add(item)
+ }
}
}
}
@@ -171,10 +169,9 @@
val mainAxisOffset = 0 - currentMainAxisOffset - item.size
currentMainAxisOffset += item.size
- val itemInfo = keyToItemInfoMap.getValue(item.key)
val positionedItem = item.position(mainAxisOffset, layoutWidth, layoutHeight)
positionedItems.add(positionedItem)
- startAnimationsIfNeeded(positionedItem, itemInfo)
+ startAnimationsIfNeeded(positionedItem)
}
currentMainAxisOffset = 0
movingAwayToEndBound.sortBy { keyToIndexMap[it.key] }
@@ -182,10 +179,9 @@
val mainAxisOffset = mainAxisLayoutSize + currentMainAxisOffset
currentMainAxisOffset += item.size
- val itemInfo = keyToItemInfoMap.getValue(item.key)
val positionedItem = item.position(mainAxisOffset, layoutWidth, layoutHeight)
positionedItems.add(positionedItem)
- startAnimationsIfNeeded(positionedItem, itemInfo)
+ startAnimationsIfNeeded(positionedItem)
}
movingInFromStartBound.clear()
@@ -196,157 +192,63 @@
}
/**
- * Returns the current animated item placement offset. By calling it only during the layout
- * phase we can skip doing remeasure on every animation frame.
- */
- fun getAnimatedOffset(
- key: Any,
- placeableIndex: Int,
- minOffset: Int,
- maxOffset: Int,
- rawOffset: IntOffset
- ): IntOffset {
- val itemInfo = keyToItemInfoMap[key] ?: return rawOffset
- val item = itemInfo.placeables[placeableIndex]
- val currentValue = item.animatedOffset.value + itemInfo.notAnimatableDelta
- val currentTarget = item.targetOffset + itemInfo.notAnimatableDelta
-
- // cancel the animation if it is fully out of the bounds.
- if (item.inProgress &&
- ((currentTarget.mainAxis <= minOffset && currentValue.mainAxis <= minOffset) ||
- (currentTarget.mainAxis >= maxOffset && currentValue.mainAxis >= maxOffset))
- ) {
- scope.launch {
- item.animatedOffset.snapTo(item.targetOffset)
- item.inProgress = false
- }
- }
-
- return currentValue
- }
-
- /**
* Should be called when the animations are not needed for the next positions change,
* for example when we snap to a new position.
*/
fun reset() {
- keyToItemInfoMap.clear()
+ activeKeys.clear()
keyToIndexMap = LazyLayoutKeyIndexMap.Empty
firstVisibleIndex = -1
}
- private fun createItemInfo(
+ private fun initializeNode(
item: LazyListPositionedItem,
- mainAxisOffset: Int = item.getOffset(0).mainAxis
- ): ItemInfo {
- val newItemInfo = ItemInfo()
+ mainAxisOffset: Int
+ ) {
val firstPlaceableOffset = item.getOffset(0)
- val targetFirstPlaceableOffset = if (isVertical) {
+ val targetFirstPlaceableOffset = if (item.isVertical) {
firstPlaceableOffset.copy(y = mainAxisOffset)
} else {
firstPlaceableOffset.copy(x = mainAxisOffset)
}
- // populate placeable info list
+ // initialize offsets
repeat(item.placeablesCount) { placeableIndex ->
- val diffToFirstPlaceableOffset =
- item.getOffset(placeableIndex) - firstPlaceableOffset
- newItemInfo.placeables.add(
- PlaceableInfo(
- targetFirstPlaceableOffset + diffToFirstPlaceableOffset,
- item.getMainAxisSize(placeableIndex)
- )
- )
+ val node = item.getParentData(placeableIndex).node
+ if (node != null) {
+ val diffToFirstPlaceableOffset =
+ item.getOffset(placeableIndex) - firstPlaceableOffset
+ node.rawOffset = targetFirstPlaceableOffset + diffToFirstPlaceableOffset
+ }
}
- return newItemInfo
}
- private fun startAnimationsIfNeeded(item: LazyListPositionedItem, itemInfo: ItemInfo) {
- // first we make sure our item info is up to date (has the item placeables count)
- while (itemInfo.placeables.size > item.placeablesCount) {
- itemInfo.placeables.removeLast()
- }
- while (itemInfo.placeables.size < item.placeablesCount) {
- val newPlaceableInfoIndex = itemInfo.placeables.size
- val rawOffset = item.getOffset(newPlaceableInfoIndex)
- itemInfo.placeables.add(
- PlaceableInfo(
- rawOffset - itemInfo.notAnimatableDelta,
- item.getMainAxisSize(newPlaceableInfoIndex)
- )
- )
- }
-
- itemInfo.placeables.fastForEachIndexed { index, placeableInfo ->
- val currentTarget = placeableInfo.targetOffset + itemInfo.notAnimatableDelta
- val currentOffset = item.getOffset(index)
- placeableInfo.mainAxisSize = item.getMainAxisSize(index)
- val animationSpec = item.getAnimationSpec(index)
- if (currentTarget != currentOffset) {
- placeableInfo.targetOffset = currentOffset - itemInfo.notAnimatableDelta
- if (animationSpec != null) {
- placeableInfo.inProgress = true
- scope.launch {
- val finalSpec = if (placeableInfo.animatedOffset.isRunning) {
- // when interrupted, use the default spring, unless the spec is a spring.
- if (animationSpec is SpringSpec<IntOffset>) animationSpec else
- InterruptionSpec
- } else {
- animationSpec
- }
-
- try {
- placeableInfo.animatedOffset.animateTo(
- placeableInfo.targetOffset,
- finalSpec
- )
- placeableInfo.inProgress = false
- } catch (_: CancellationException) {
- // we don't reset inProgress in case of cancellation as it means
- // there is a new animation started which would reset it later
- }
- }
+ private fun startAnimationsIfNeeded(item: LazyListPositionedItem) {
+ repeat(item.placeablesCount) { placeableIndex ->
+ val node = item.getParentData(placeableIndex).node
+ if (node != null) {
+ val newTarget = item.getOffset(placeableIndex)
+ val currentTarget = node.rawOffset
+ if (currentTarget == LazyLayoutAnimateItemModifierNode.NotInitialized) {
+ node.rawOffset = newTarget
+ } else if (currentTarget != newTarget) {
+ node.rawOffset = newTarget
+ node.animatePlacementDelta(newTarget - currentTarget)
}
}
}
}
- /**
- * Whether at least one placeable is within the viewport bounds.
- */
- private fun ItemInfo.isWithinBounds(mainAxisLayoutSize: Int): Boolean {
- return placeables.fastAny {
- val currentTarget = it.targetOffset + notAnimatableDelta
- currentTarget.mainAxis + it.mainAxisSize > 0 &&
- currentTarget.mainAxis < mainAxisLayoutSize
+ private val Any?.node get() = this as? LazyLayoutAnimateItemModifierNode
+
+ private val LazyListPositionedItem.hasAnimations: Boolean
+ get() {
+ repeat(placeablesCount) { index ->
+ if (getParentData(index).node != null) {
+ return true
+ }
+ }
+ return false
}
- }
-
- private fun Int.toOffset() =
- IntOffset(if (isVertical) 0 else this, if (!isVertical) 0 else this)
-
- private val IntOffset.mainAxis get() = if (isVertical) y else x
}
-
-private class ItemInfo {
- var notAnimatableDelta: IntOffset = IntOffset.Zero
- val placeables = mutableListOf<PlaceableInfo>()
-}
-
-private class PlaceableInfo(
- initialOffset: IntOffset,
- var mainAxisSize: Int
-) {
- val animatedOffset = Animatable(initialOffset, IntOffset.VectorConverter)
- var targetOffset: IntOffset = initialOffset
- var inProgress by mutableStateOf(false)
-}
-
-/**
- * We switch to this spec when a duration based animation is being interrupted.
- */
-private val InterruptionSpec = spring(
- stiffness = Spring.StiffnessMediumLow,
- visibilityThreshold = IntOffset.VisibilityThreshold
-)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
index ac0811d..0c97ea2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
@@ -20,8 +20,6 @@
import androidx.compose.foundation.fastFilter
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
-import androidx.compose.foundation.lazy.layout.findIndexByKey
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
@@ -31,7 +29,6 @@
import androidx.compose.ui.unit.constrainWidth
import androidx.compose.ui.util.fastForEach
import kotlin.math.abs
-import kotlin.math.min
import kotlin.math.roundToInt
import kotlin.math.sign
@@ -42,7 +39,6 @@
@OptIn(ExperimentalFoundationApi::class)
internal fun measureLazyList(
itemsCount: Int,
- itemProvider: LazyListItemProvider,
measuredItemProvider: LazyListMeasuredItemProvider,
mainAxisAvailableSize: Int,
beforeContentPadding: Int,
@@ -59,9 +55,8 @@
reverseLayout: Boolean,
density: Density,
placementAnimator: LazyListItemPlacementAnimator,
- beyondBoundsInfo: LazyListBeyondBoundsInfo,
beyondBoundsItemCount: Int,
- pinnedItems: LazyLayoutPinnedItemList,
+ pinnedItems: List<Int>,
layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
): LazyListMeasureResult {
require(beforeContentPadding >= 0)
@@ -235,11 +230,8 @@
// Compose extra items before
val extraItemsBefore = createItemsBeforeList(
- beyondBoundsInfo = beyondBoundsInfo,
currentFirstItemIndex = currentFirstItemIndex,
measuredItemProvider = measuredItemProvider,
- itemProvider = itemProvider,
- itemsCount = itemsCount,
beyondBoundsItemCount = beyondBoundsItemCount,
pinnedItems = pinnedItems
)
@@ -251,10 +243,8 @@
// Compose items after last item
val extraItemsAfter = createItemsAfterList(
- beyondBoundsInfo = beyondBoundsInfo,
visibleItems = visibleItems,
measuredItemProvider = measuredItemProvider,
- itemProvider = itemProvider,
itemsCount = itemsCount,
beyondBoundsItemCount = beyondBoundsItemCount,
pinnedItems = pinnedItems
@@ -295,7 +285,8 @@
layoutWidth = layoutWidth,
layoutHeight = layoutHeight,
positionedItems = positionedItems,
- itemProvider = measuredItemProvider
+ itemProvider = measuredItemProvider,
+ isVertical = isVertical
)
val headerItem = if (headerIndexes.isNotEmpty()) {
@@ -340,18 +331,13 @@
}
}
-@OptIn(ExperimentalFoundationApi::class)
private fun createItemsAfterList(
- beyondBoundsInfo: LazyListBeyondBoundsInfo,
visibleItems: MutableList<LazyListMeasuredItem>,
measuredItemProvider: LazyListMeasuredItemProvider,
- itemProvider: LazyListItemProvider,
itemsCount: Int,
beyondBoundsItemCount: Int,
- pinnedItems: LazyLayoutPinnedItemList
+ pinnedItems: List<Int>
): List<LazyListMeasuredItem> {
- fun LazyListBeyondBoundsInfo.endIndex() = min(end, itemsCount - 1)
-
var list: MutableList<LazyListMeasuredItem>? = null
var end = visibleItems.last().index
@@ -363,19 +349,14 @@
)
}
- if (beyondBoundsInfo.hasIntervals()) {
- end = maxOf(beyondBoundsInfo.endIndex(), end)
- }
-
end = minOf(end + beyondBoundsItemCount, itemsCount - 1)
for (i in visibleItems.last().index + 1..end) {
addItem(i)
}
- pinnedItems.fastForEach { item ->
- val index = itemProvider.findIndexByKey(item.key, item.index)
- if (index > end && index < itemsCount) {
+ pinnedItems.fastForEach { index ->
+ if (index > end) {
addItem(index)
}
}
@@ -383,18 +364,12 @@
return list ?: emptyList()
}
-@OptIn(ExperimentalFoundationApi::class)
private fun createItemsBeforeList(
- beyondBoundsInfo: LazyListBeyondBoundsInfo,
currentFirstItemIndex: DataIndex,
measuredItemProvider: LazyListMeasuredItemProvider,
- itemProvider: LazyListItemProvider,
- itemsCount: Int,
beyondBoundsItemCount: Int,
- pinnedItems: LazyLayoutPinnedItemList
+ pinnedItems: List<Int>
): List<LazyListMeasuredItem> {
- fun LazyListBeyondBoundsInfo.startIndex() = min(start, itemsCount - 1)
-
var list: MutableList<LazyListMeasuredItem>? = null
var start = currentFirstItemIndex.value
@@ -406,18 +381,13 @@
)
}
- if (beyondBoundsInfo.hasIntervals()) {
- start = minOf(beyondBoundsInfo.startIndex(), start)
- }
-
start = maxOf(0, start - beyondBoundsItemCount)
for (i in currentFirstItemIndex.value - 1 downTo start) {
addItem(i)
}
- pinnedItems.fastForEach { item ->
- val index = itemProvider.findIndexByKey(item.key, item.index)
+ pinnedItems.fastForEach { index ->
if (index < start) {
addItem(index)
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt
index 02bd8ef..443ccee 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt
@@ -16,8 +16,8 @@
package androidx.compose.foundation.lazy
-import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
import androidx.compose.ui.Alignment
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.IntOffset
@@ -38,7 +38,6 @@
private val reverseLayout: Boolean,
private val beforeContentPadding: Int,
private val afterContentPadding: Int,
- private val placementAnimator: LazyListItemPlacementAnimator,
/**
* Extra spacing to be added to [size] aside from the sum of the [placeables] size. It
* is usually representing the spacing after the item.
@@ -78,6 +77,10 @@
crossAxisSize = maxCrossAxis
}
+ val placeablesCount: Int get() = placeables.size
+
+ fun getParentData(index: Int) = placeables[index].parentData
+
/**
* Calculates positions for the inner placeables at [offset] main axis position.
* If [reverseOrder] is true the inner placeables would be placed in the inverted order.
@@ -111,7 +114,6 @@
maxMainAxisOffset = mainAxisLayoutSize + afterContentPadding,
isVertical = isVertical,
wrappers = wrappers,
- placementAnimator = placementAnimator,
visualOffset = visualOffset,
reverseLayout = reverseLayout,
mainAxisLayoutSize = mainAxisLayoutSize
@@ -126,9 +128,8 @@
override val size: Int,
private val minMainAxisOffset: Int,
private val maxMainAxisOffset: Int,
- private val isVertical: Boolean,
+ val isVertical: Boolean,
private val wrappers: List<LazyListPlaceableWrapper>,
- private val placementAnimator: LazyListItemPlacementAnimator,
private val visualOffset: IntOffset,
private val reverseLayout: Boolean,
private val mainAxisLayoutSize: Int
@@ -137,20 +138,7 @@
fun getOffset(index: Int) = wrappers[index].offset
- fun getMainAxisSize(index: Int) = wrappers[index].placeable.mainAxisSize
-
- @Suppress("UNCHECKED_CAST")
- fun getAnimationSpec(index: Int) =
- wrappers[index].placeable.parentData as? FiniteAnimationSpec<IntOffset>?
-
- val hasAnimations = run {
- repeat(placeablesCount) { index ->
- if (getAnimationSpec(index) != null) {
- return@run true
- }
- }
- false
- }
+ fun getParentData(index: Int) = wrappers[index].placeable.parentData
fun place(
scope: Placeable.PlacementScope,
@@ -159,28 +147,33 @@
val placeable = wrappers[index].placeable
val minOffset = minMainAxisOffset - placeable.mainAxisSize
val maxOffset = maxMainAxisOffset
- val offset = if (getAnimationSpec(index) != null) {
- placementAnimator.getAnimatedOffset(
- key, index, minOffset, maxOffset, getOffset(index)
- )
- } else {
- getOffset(index)
+ var offset = getOffset(index)
+ val animateNode = getParentData(index) as? LazyLayoutAnimateItemModifierNode
+ if (animateNode != null) {
+ val animatedOffset = offset + animateNode.placementDelta
+ // cancel the animation if current and target offsets are both out of the bounds.
+ if ((offset.mainAxis <= minOffset && animatedOffset.mainAxis <= minOffset) ||
+ (offset.mainAxis >= maxOffset && animatedOffset.mainAxis >= maxOffset)
+ ) {
+ animateNode.cancelAnimation()
+ }
+ offset = animatedOffset
}
- val reverseLayoutAwareOffset = if (reverseLayout) {
- offset.copy { mainAxisOffset ->
+ if (reverseLayout) {
+ offset = offset.copy { mainAxisOffset ->
mainAxisLayoutSize - mainAxisOffset - placeable.mainAxisSize
}
- } else {
- offset
}
+ offset += visualOffset
if (isVertical) {
- placeable.placeWithLayer(reverseLayoutAwareOffset + visualOffset)
+ placeable.placeWithLayer(offset)
} else {
- placeable.placeRelativeWithLayer(reverseLayoutAwareOffset + visualOffset)
+ placeable.placeRelativeWithLayer(offset)
}
}
}
+ private val IntOffset.mainAxis get() = if (isVertical) y else x
private val Placeable.mainAxisSize get() = if (isVertical) height else width
private inline fun IntOffset.copy(mainAxisMap: (Int) -> Int): IntOffset =
IntOffset(if (isVertical) x else mainAxisMap(x), if (isVertical) mainAxisMap(y) else y)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
index c0756a3..f3d19f1 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
@@ -214,7 +214,7 @@
*/
internal val awaitLayoutModifier = AwaitFirstLayoutModifier()
- internal var placementAnimator by mutableStateOf<LazyListItemPlacementAnimator?>(null)
+ internal val placementAnimator = LazyListItemPlacementAnimator()
/**
* Constraints passed to the prefetcher for premeasuring the prefetched items.
@@ -248,7 +248,7 @@
internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
scrollPosition.requestPosition(DataIndex(index), scrollOffset)
// placement animation is not needed because we snap into a new position.
- placementAnimator?.reset()
+ placementAnimator.reset()
remeasurement?.forceRemeasure()
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
index 704d6ef..ec71a7b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
@@ -33,7 +33,6 @@
import androidx.compose.foundation.overscroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.MeasureResult
@@ -79,12 +78,6 @@
val semanticState = rememberLazyGridSemanticState(state, reverseLayout)
- val scope = rememberCoroutineScope()
- val placementAnimator = remember(state, isVertical) {
- LazyGridItemPlacementAnimator(scope, isVertical)
- }
- state.placementAnimator = placementAnimator
-
val measurePolicy = rememberLazyGridMeasurePolicy(
itemProvider,
state,
@@ -93,8 +86,7 @@
reverseLayout,
isVertical,
horizontalArrangement,
- verticalArrangement,
- placementAnimator
+ verticalArrangement
)
state.isVertical = isVertical
@@ -171,8 +163,6 @@
horizontalArrangement: Arrangement.Horizontal? = null,
/** The vertical arrangement for items. Required when isVertical is true */
verticalArrangement: Arrangement.Vertical? = null,
- /** Item placement animator. Should be notified with the measuring result */
- placementAnimator: LazyGridItemPlacementAnimator
) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
state,
slots,
@@ -180,8 +170,7 @@
reverseLayout,
isVertical,
horizontalArrangement,
- verticalArrangement,
- placementAnimator
+ verticalArrangement
) {
{ containerConstraints ->
checkScrollableContainerConstraints(
@@ -273,8 +262,7 @@
beforeContentPadding = beforeContentPadding,
afterContentPadding = afterContentPadding,
visualOffset = visualItemOffset,
- placeables = placeables,
- placementAnimator = placementAnimator
+ placeables = placeables
)
}
val measuredLineProvider = LazyGridMeasuredLineProvider(
@@ -344,7 +332,7 @@
horizontalArrangement = horizontalArrangement,
reverseLayout = reverseLayout,
density = this,
- placementAnimator = placementAnimator,
+ placementAnimator = state.placementAnimator,
spanLayoutProvider = spanLayoutProvider,
pinnedItems = state.pinnedItems,
layout = { width, height, placement ->
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
index 98ffdb3..5bdc836 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
@@ -16,45 +16,27 @@
package androidx.compose.foundation.lazy.grid
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.Spring
-import androidx.compose.animation.core.SpringSpec
-import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.VisibilityThreshold
-import androidx.compose.animation.core.spring
-import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastForEach
-import androidx.compose.ui.util.fastForEachIndexed
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
/**
- * Handles the item placement animations when it is set via
- * [LazyGridItemScope.animateItemPlacement].
+ * Handles the item placement animations when it is set via [LazyGridItemScope.animateItemPlacement].
*
* This class is responsible for detecting when item position changed, figuring our start/end
* offsets and starting the animations.
*/
-@OptIn(ExperimentalFoundationApi::class)
-internal class LazyGridItemPlacementAnimator(
- private val scope: CoroutineScope,
- private val isVertical: Boolean
-) {
- // state containing an animation and all relevant info for each item.
+internal class LazyGridItemPlacementAnimator {
+ // state containing relevant info for active items.
private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
// snapshot of the key to index map used for the last measuring.
private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
- // keeps the index of the first visible item.
+ // keeps the index of the first visible item index.
private var firstVisibleIndex = 0
// stored to not allocate it every pass.
@@ -75,7 +57,8 @@
layoutHeight: Int,
positionedItems: MutableList<LazyGridPositionedItem>,
itemProvider: LazyGridMeasuredItemProvider,
- spanLayoutProvider: LazyGridSpanLayoutProvider
+ spanLayoutProvider: LazyGridSpanLayoutProvider,
+ isVertical: Boolean
) {
if (!positionedItems.fastAny { it.hasAnimations } && keyToItemInfoMap.isEmpty()) {
// no animations specified - no work needed
@@ -91,18 +74,24 @@
val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
// the consumed scroll is considered as a delta we don't need to animate
- val notAnimatableDelta = consumedScroll.toOffset()
+ val scrollOffset = if (isVertical) {
+ IntOffset(0, consumedScroll)
+ } else {
+ IntOffset(consumedScroll, 0)
+ }
// first add all items we had in the previous run
movingAwayKeys.addAll(keyToItemInfoMap.keys)
// iterate through the items which are visible (without animated offsets)
positionedItems.fastForEach { item ->
- // remove items we have in the current one as they are not disappearing.
+ // remove items we have in the current one as they are still visible.
movingAwayKeys.remove(item.key)
if (item.hasAnimations) {
val itemInfo = keyToItemInfoMap[item.key]
// there is no state associated with this item yet
if (itemInfo == null) {
+ keyToItemInfoMap[item.key] =
+ ItemInfo(item.getCrossAxisSize(), item.getCrossAxisOffset())
val previousIndex = previousKeyToIndexMap[item.key]
if (previousIndex != -1 && item.index != previousIndex) {
if (previousIndex < previousFirstVisibleIndex) {
@@ -112,14 +101,22 @@
movingInFromEndBound.add(item)
}
} else {
- keyToItemInfoMap[item.key] = createItemInfo(item)
+ initializeNode(
+ item,
+ item.offset.let { if (item.isVertical) it.y else it.x }
+ )
}
} else {
- // this item was visible and is still visible.
- itemInfo.notAnimatableDelta += notAnimatableDelta // apply new scroll delta
+ repeat(item.placeablesCount) { placeableIndex ->
+ item.getParentData(placeableIndex).node?.apply {
+ if (rawOffset != LazyLayoutAnimateItemModifierNode.NotInitialized) {
+ rawOffset += scrollOffset
+ }
+ }
+ }
itemInfo.crossAxisSize = item.getCrossAxisSize()
itemInfo.crossAxisOffset = item.getCrossAxisOffset()
- startAnimationsIfNeeded(item, itemInfo)
+ startAnimationsIfNeeded(item)
}
} else {
// no animation, clean up if needed
@@ -128,11 +125,11 @@
}
var currentMainAxisOffset = 0
- movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
var previousLine = -1
var previousLineMainAxisSize = 0
+ movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
movingInFromStartBound.fastForEach { item ->
- val line = item.line
+ val line = if (isVertical) item.row else item.column
if (line != -1 && line == previousLine) {
previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.getMainAxisSize())
} else {
@@ -141,16 +138,15 @@
previousLine = line
}
val mainAxisOffset = 0 - currentMainAxisOffset - item.getMainAxisSize()
- val itemInfo = createItemInfo(item, mainAxisOffset)
- keyToItemInfoMap[item.key] = itemInfo
- startAnimationsIfNeeded(item, itemInfo)
+ initializeNode(item, mainAxisOffset)
+ startAnimationsIfNeeded(item)
}
currentMainAxisOffset = 0
previousLine = -1
previousLineMainAxisSize = 0
movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
movingInFromEndBound.fastForEach { item ->
- val line = item.line
+ val line = if (isVertical) item.row else item.column
if (line != -1 && line == previousLine) {
previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.getMainAxisSize())
} else {
@@ -159,9 +155,8 @@
previousLine = line
}
val mainAxisOffset = mainAxisLayoutSize + currentMainAxisOffset
- val itemInfo = createItemInfo(item, mainAxisOffset)
- keyToItemInfoMap[item.key] = itemInfo
- startAnimationsIfNeeded(item, itemInfo)
+ initializeNode(item, mainAxisOffset)
+ startAnimationsIfNeeded(item)
}
movingAwayKeys.forEach { key ->
@@ -170,13 +165,7 @@
val itemInfo = keyToItemInfoMap.getValue(key)
val newIndex = keyToIndexMap[key]
- // whether the animation associated with the item has been finished or not yet started
- val inProgress = itemInfo.placeables.fastAny { it.inProgress }
- if (itemInfo.placeables.isEmpty() ||
- newIndex == -1 ||
- (!inProgress && newIndex == previousKeyToIndexMap[key]) ||
- (!inProgress && !itemInfo.isWithinBounds(mainAxisLayoutSize))
- ) {
+ if (newIndex == -1) {
keyToItemInfoMap.remove(key)
} else {
val item = itemProvider.getAndMeasure(
@@ -187,10 +176,22 @@
Constraints.fixedHeight(itemInfo.crossAxisSize)
}
)
- if (newIndex < firstVisibleIndex) {
- movingAwayToStartBound.add(item)
+ // check if we have any active placement animation on the item
+ var inProgress = false
+ repeat(item.placeablesCount) {
+ if (item.getParentData(it).node?.isAnimationInProgress == true) {
+ inProgress = true
+ return@repeat
+ }
+ }
+ if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+ keyToItemInfoMap.remove(key)
} else {
- movingAwayToEndBound.add(item)
+ if (newIndex < firstVisibleIndex) {
+ movingAwayToStartBound.add(item)
+ } else {
+ movingAwayToEndBound.add(item)
+ }
}
}
}
@@ -221,7 +222,7 @@
LazyGridItemInfo.UnknownColumn
)
positionedItems.add(positionedItem)
- startAnimationsIfNeeded(positionedItem, itemInfo)
+ startAnimationsIfNeeded(positionedItem)
}
currentMainAxisOffset = 0
previousLine = -1
@@ -249,7 +250,7 @@
)
positionedItems.add(positionedItem)
- startAnimationsIfNeeded(positionedItem, itemInfo)
+ startAnimationsIfNeeded(positionedItem)
}
movingInFromStartBound.clear()
@@ -260,36 +261,6 @@
}
/**
- * Returns the current animated item placement offset. By calling it only during the layout
- * phase we can skip doing remeasure on every animation frame.
- */
- fun getAnimatedOffset(
- key: Any,
- placeableIndex: Int,
- minOffset: Int,
- maxOffset: Int,
- rawOffset: IntOffset
- ): IntOffset {
- val itemInfo = keyToItemInfoMap[key] ?: return rawOffset
- val item = itemInfo.placeables[placeableIndex]
- val currentValue = item.animatedOffset.value + itemInfo.notAnimatableDelta
- val currentTarget = item.targetOffset + itemInfo.notAnimatableDelta
-
- // cancel the animation if it is fully out of the bounds.
- if (item.inProgress &&
- ((currentTarget.mainAxis <= minOffset && currentValue.mainAxis < minOffset) ||
- (currentTarget.mainAxis >= maxOffset && currentValue.mainAxis > maxOffset))
- ) {
- scope.launch {
- item.animatedOffset.snapTo(item.targetOffset)
- item.inProgress = false
- }
- }
-
- return currentValue
- }
-
- /**
* Should be called when the animations are not needed for the next positions change,
* for example when we snap to a new position.
*/
@@ -299,116 +270,59 @@
firstVisibleIndex = -1
}
- private fun createItemInfo(
+ private fun initializeNode(
item: LazyGridPositionedItem,
- mainAxisOffset: Int = item.offset.mainAxis
- ): ItemInfo {
- val newItemInfo = ItemInfo(item.getCrossAxisSize(), item.getCrossAxisOffset())
- val targetOffset = if (isVertical) {
- item.offset.copy(y = mainAxisOffset)
+ mainAxisOffset: Int
+ ) {
+ val firstPlaceableOffset = item.offset
+
+ val targetFirstPlaceableOffset = if (item.isVertical) {
+ firstPlaceableOffset.copy(y = mainAxisOffset)
} else {
- item.offset.copy(x = mainAxisOffset)
+ firstPlaceableOffset.copy(x = mainAxisOffset)
}
- // populate placeable info list
+ // initialize offsets
repeat(item.placeablesCount) { placeableIndex ->
- newItemInfo.placeables.add(
- PlaceableInfo(
- targetOffset,
- item.getMainAxisSize(placeableIndex)
- )
- )
+ val node = item.getParentData(placeableIndex).node
+ if (node != null) {
+ val diffToFirstPlaceableOffset =
+ item.offset - firstPlaceableOffset
+ node.rawOffset = targetFirstPlaceableOffset + diffToFirstPlaceableOffset
+ }
}
- return newItemInfo
}
- private fun startAnimationsIfNeeded(item: LazyGridPositionedItem, itemInfo: ItemInfo) {
- // first we make sure our item info is up to date (has the item placeables count)
- while (itemInfo.placeables.size > item.placeablesCount) {
- itemInfo.placeables.removeLast()
- }
- while (itemInfo.placeables.size < item.placeablesCount) {
- val newPlaceableInfoIndex = itemInfo.placeables.size
- val rawOffset = item.offset
- itemInfo.placeables.add(
- PlaceableInfo(
- rawOffset - itemInfo.notAnimatableDelta,
- item.getMainAxisSize(newPlaceableInfoIndex)
- )
- )
- }
-
- itemInfo.placeables.fastForEachIndexed { index, placeableInfo ->
- val currentTarget = placeableInfo.targetOffset + itemInfo.notAnimatableDelta
- val currentOffset = item.offset
- placeableInfo.mainAxisSize = item.getMainAxisSize(index)
- val animationSpec = item.getAnimationSpec(index)
- if (currentTarget != currentOffset) {
- placeableInfo.targetOffset = currentOffset - itemInfo.notAnimatableDelta
- if (animationSpec != null) {
- placeableInfo.inProgress = true
- scope.launch {
- val finalSpec = if (placeableInfo.animatedOffset.isRunning) {
- // when interrupted, use the default spring, unless the spec is a spring.
- if (animationSpec is SpringSpec<IntOffset>) animationSpec else
- InterruptionSpec
- } else {
- animationSpec
- }
-
- try {
- placeableInfo.animatedOffset.animateTo(
- placeableInfo.targetOffset,
- finalSpec
- )
- placeableInfo.inProgress = false
- } catch (_: CancellationException) {
- // we don't reset inProgress in case of cancellation as it means
- // there is a new animation started which would reset it later
- }
- }
+ private fun startAnimationsIfNeeded(item: LazyGridPositionedItem) {
+ repeat(item.placeablesCount) { placeableIndex ->
+ val node = item.getParentData(placeableIndex).node
+ if (node != null) {
+ val newTarget = item.offset
+ val currentTarget = node.rawOffset
+ if (currentTarget == LazyLayoutAnimateItemModifierNode.NotInitialized) {
+ node.rawOffset = item.offset
+ } else if (currentTarget != newTarget) {
+ node.rawOffset = newTarget
+ node.animatePlacementDelta(item.offset - currentTarget)
}
}
}
}
- /**
- * Whether at least one placeable is within the viewport bounds.
- */
- private fun ItemInfo.isWithinBounds(mainAxisLayoutSize: Int): Boolean {
- return placeables.fastAny {
- val currentTarget = it.targetOffset + notAnimatableDelta
- currentTarget.mainAxis + it.mainAxisSize > 0 &&
- currentTarget.mainAxis < mainAxisLayoutSize
+ private val Any?.node get() = this as? LazyLayoutAnimateItemModifierNode
+
+ private val LazyGridPositionedItem.hasAnimations: Boolean
+ get() {
+ repeat(placeablesCount) { index ->
+ if (getParentData(index).node != null) {
+ return true
+ }
+ }
+ return false
}
- }
-
- private fun Int.toOffset() =
- IntOffset(if (isVertical) 0 else this, if (!isVertical) 0 else this)
-
- private val IntOffset.mainAxis get() = if (isVertical) y else x
-
- private val LazyGridPositionedItem.line get() = if (isVertical) row else column
}
private class ItemInfo(
var crossAxisSize: Int,
var crossAxisOffset: Int
-) {
- var notAnimatableDelta: IntOffset = IntOffset.Zero
- val placeables = mutableListOf<PlaceableInfo>()
-}
-
-private class PlaceableInfo(initialOffset: IntOffset, var mainAxisSize: Int) {
- val animatedOffset = Animatable(initialOffset, IntOffset.VectorConverter)
- var targetOffset: IntOffset = initialOffset
- var inProgress by mutableStateOf(false)
-}
-
-/**
- * We switch to this spec when a duration based animation is being interrupted.
- */
-private val InterruptionSpec = spring(
- stiffness = Spring.StiffnessMediumLow,
- visibilityThreshold = IntOffset.VisibilityThreshold
)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt
index 79d7926..f8dda36 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemScopeImpl.kt
@@ -18,7 +18,9 @@
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
import androidx.compose.ui.Modifier
+import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.ParentDataModifierNode
import androidx.compose.ui.platform.InspectorInfo
@@ -35,10 +37,11 @@
private class AnimateItemPlacementElement(
val animationSpec: FiniteAnimationSpec<IntOffset>
) : ModifierNodeElement<AnimateItemPlacementNode>() {
+
override fun create(): AnimateItemPlacementNode = AnimateItemPlacementNode(animationSpec)
override fun update(node: AnimateItemPlacementNode): AnimateItemPlacementNode = node.also {
- it.animationSpec = animationSpec
+ it.delegatingNode.placementAnimationSpec = animationSpec
}
override fun equals(other: Any?): Boolean {
@@ -58,7 +61,10 @@
}
private class AnimateItemPlacementNode(
- var animationSpec: FiniteAnimationSpec<IntOffset>
-) : Modifier.Node(), ParentDataModifierNode {
- override fun Density.modifyParentData(parentData: Any?): Any = animationSpec
+ animationSpec: FiniteAnimationSpec<IntOffset>
+) : DelegatingNode(), ParentDataModifierNode {
+
+ val delegatingNode = delegated { LazyLayoutAnimateItemModifierNode(animationSpec) }
+
+ override fun Density.modifyParentData(parentData: Any?): Any = delegatingNode
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
index 6d18f7b..b22522a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
@@ -274,7 +274,8 @@
layoutHeight = layoutHeight,
positionedItems = positionedItems,
itemProvider = measuredItemProvider,
- spanLayoutProvider = spanLayoutProvider
+ spanLayoutProvider = spanLayoutProvider,
+ isVertical = isVertical
)
return LazyGridMeasureResult(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
index eff4278..481564d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
@@ -16,8 +16,7 @@
package androidx.compose.foundation.lazy.grid
-import androidx.compose.animation.core.FiniteAnimationSpec
-import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
@@ -28,7 +27,6 @@
* Represents one measured item of the lazy grid. It can in fact consist of multiple placeables
* if the user emit multiple layout nodes in the item callback.
*/
-@OptIn(ExperimentalFoundationApi::class)
internal class LazyGridMeasuredItem(
val index: ItemIndex,
val key: Any,
@@ -44,7 +42,6 @@
private val beforeContentPadding: Int,
private val afterContentPadding: Int,
val placeables: List<Placeable>,
- private val placementAnimator: LazyGridItemPlacementAnimator,
/**
* The offset which shouldn't affect any calculations but needs to be applied for the final
* value passed into the place() call.
@@ -61,6 +58,10 @@
*/
val mainAxisSizeWithSpacings: Int
+ val placeablesCount: Int get() = placeables.size
+
+ fun getParentData(index: Int) = placeables[index].parentData
+
init {
var maxMainAxis = 0
placeables.fastForEach {
@@ -112,7 +113,6 @@
maxMainAxisOffset = mainAxisLayoutSize + afterContentPadding,
isVertical = isVertical,
placeables = placeables,
- placementAnimator = placementAnimator,
visualOffset = visualOffset,
mainAxisLayoutSize = mainAxisLayoutSize,
reverseLayout = reverseLayout
@@ -129,35 +129,21 @@
override val size: IntSize,
private val minMainAxisOffset: Int,
private val maxMainAxisOffset: Int,
- private val isVertical: Boolean,
+ val isVertical: Boolean,
private val placeables: List<Placeable>,
- private val placementAnimator: LazyGridItemPlacementAnimator,
private val visualOffset: IntOffset,
private val mainAxisLayoutSize: Int,
private val reverseLayout: Boolean
) : LazyGridItemInfo {
val placeablesCount: Int get() = placeables.size
- fun getMainAxisSize(index: Int) = placeables[index].mainAxisSize
-
fun getMainAxisSize() = if (isVertical) size.height else size.width
fun getCrossAxisSize() = if (isVertical) size.width else size.height
fun getCrossAxisOffset() = if (isVertical) offset.x else offset.y
- @Suppress("UNCHECKED_CAST")
- fun getAnimationSpec(index: Int) =
- placeables[index].parentData as? FiniteAnimationSpec<IntOffset>?
-
- val hasAnimations = run {
- repeat(placeablesCount) { index ->
- if (getAnimationSpec(index) != null) {
- return@run true
- }
- }
- false
- }
+ fun getParentData(index: Int) = placeables[index].parentData
fun place(
scope: Placeable.PlacementScope,
@@ -166,29 +152,34 @@
val placeable = placeables[index]
val minOffset = minMainAxisOffset - placeable.mainAxisSize
val maxOffset = maxMainAxisOffset
- val offset = if (getAnimationSpec(index) != null) {
- placementAnimator.getAnimatedOffset(
- key, index, minOffset, maxOffset, offset
- )
- } else {
- offset
- }
- val reverseLayoutAwareOffset = if (reverseLayout) {
- offset.copy { mainAxisOffset ->
+ var offset = offset
+ val animateNode = getParentData(index) as? LazyLayoutAnimateItemModifierNode
+ if (animateNode != null) {
+ val animatedOffset = offset + animateNode.placementDelta
+ // cancel the animation if current and target offsets are both out of the bounds.
+ if ((offset.mainAxis <= minOffset && animatedOffset.mainAxis <= minOffset) ||
+ (offset.mainAxis >= maxOffset && animatedOffset.mainAxis >= maxOffset)
+ ) {
+ animateNode.cancelAnimation()
+ }
+ offset = animatedOffset
+ }
+ if (reverseLayout) {
+ offset = offset.copy { mainAxisOffset ->
mainAxisLayoutSize - mainAxisOffset - placeable.mainAxisSize
}
- } else {
- offset
}
+ offset += visualOffset
if (isVertical) {
- placeable.placeWithLayer(reverseLayoutAwareOffset + visualOffset)
+ placeable.placeWithLayer(offset)
} else {
- placeable.placeRelativeWithLayer(reverseLayoutAwareOffset + visualOffset)
+ placeable.placeRelativeWithLayer(offset)
}
}
}
+ private val IntOffset.mainAxis get() = if (isVertical) y else x
private val Placeable.mainAxisSize get() = if (isVertical) height else width
private inline fun IntOffset.copy(mainAxisMap: (Int) -> Int): IntOffset =
IntOffset(if (isVertical) x else mainAxisMap(x), if (isVertical) mainAxisMap(y) else y)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
index 25fd5f5..87934a4 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
@@ -223,7 +223,7 @@
internal var prefetchInfoRetriever: (line: LineIndex) -> List<Pair<Int, Constraints>> by
mutableStateOf({ emptyList() })
- internal var placementAnimator by mutableStateOf<LazyGridItemPlacementAnimator?>(null)
+ internal val placementAnimator = LazyGridItemPlacementAnimator()
private val animateScrollScope = LazyGridAnimateScrollScope(this)
@@ -254,7 +254,7 @@
internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
scrollPosition.requestPosition(ItemIndex(index), scrollOffset)
// placement animation is not needed because we snap into a new position.
- placementAnimator?.reset()
+ placementAnimator.reset()
remeasurement?.forceRemeasure()
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
new file mode 100644
index 0000000..5623db2
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.lazy.layout
+
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.FiniteAnimationSpec
+import androidx.compose.animation.core.Spring
+import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.VectorConverter
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.IntOffset
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.launch
+
+internal class LazyLayoutAnimateItemModifierNode(
+ var placementAnimationSpec: FiniteAnimationSpec<IntOffset>
+) : Modifier.Node() {
+
+ /**
+ * Returns true when the placement animation is currently in progress so the parent
+ * should continue composing this item.
+ */
+ var isAnimationInProgress by mutableStateOf(false)
+ private set
+
+ /**
+ * This property is managed by the animation manager and is not directly used by this class.
+ * It represents the last known offset of this item in the lazy layout coordinate space.
+ * It will be updated on every scroll and is allowing the manager to track when the item
+ * position changes not because of the scroll event in order to start the animation.
+ * When there is an active animation it represents the final/target offset.
+ */
+ var rawOffset: IntOffset = NotInitialized
+
+ private val placementDeltaAnimation = Animatable(IntOffset.Zero, IntOffset.VectorConverter)
+
+ /**
+ * Current delta to apply for a placement offset. Updates every animation frame.
+ * The settled value is [IntOffset.Zero] so the animation is always targeting this value.
+ */
+ var placementDelta by mutableStateOf(IntOffset.Zero)
+ private set
+
+ /**
+ * Cancels the ongoing animation if there is one.
+ */
+ fun cancelAnimation() {
+ if (isAnimationInProgress) {
+ coroutineScope.launch {
+ placementDeltaAnimation.snapTo(IntOffset.Zero)
+ placementDelta = IntOffset.Zero
+ isAnimationInProgress = false
+ }
+ }
+ }
+
+ /**
+ * Animate the placement by the given [delta] offset.
+ */
+ fun animatePlacementDelta(delta: IntOffset) {
+ val totalDelta = placementDelta - delta
+ placementDelta = totalDelta
+ isAnimationInProgress = true
+ coroutineScope.launch {
+ try {
+ val spec = if (placementDeltaAnimation.isRunning) {
+ // when interrupted, use the default spring, unless the spec is a spring.
+ if (placementAnimationSpec is SpringSpec<IntOffset>) {
+ placementAnimationSpec
+ } else {
+ InterruptionSpec
+ }
+ } else {
+ placementAnimationSpec
+ }
+ val startVelocity = placementDeltaAnimation.velocity
+ placementDeltaAnimation.snapTo(totalDelta)
+ placementDeltaAnimation.animateTo(IntOffset.Zero, spec, startVelocity) {
+ placementDelta = value
+ }
+
+ isAnimationInProgress = false
+ } catch (_: CancellationException) {
+ // we don't reset inProgress in case of cancellation as it means
+ // there is a new animation started which would reset it later
+ }
+ }
+ }
+
+ override fun onDetach() {
+ placementDelta = IntOffset.Zero
+ isAnimationInProgress = false
+ rawOffset = NotInitialized
+ // placementDeltaAnimation will be canceled because coroutineScope will be canceled.
+ }
+
+ companion object {
+ val NotInitialized = IntOffset(Int.MAX_VALUE, Int.MAX_VALUE)
+ }
+}
+
+/**
+ * We switch to this spec when a duration based animation is being interrupted.
+ */
+private val InterruptionSpec = spring(
+ stiffness = Spring.StiffnessMediumLow,
+ visibilityThreshold = IntOffset.VisibilityThreshold
+)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
index 939fe3e..822a91c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutBeyondBoundsModifierLocal.kt
@@ -62,11 +62,12 @@
}
// We use a new interval each time because this function is re-entrant.
- var interval = beyondBoundsInfo.addInterval(
- state.firstVisibleIndex,
+ val startIndex = if (direction.isForward()) {
state.lastVisibleIndex
- )
-
+ } else {
+ state.firstVisibleIndex
+ }
+ var interval = beyondBoundsInfo.addInterval(startIndex, startIndex)
var found: T? = null
while (found == null && interval.hasMoreContent(direction)) {
@@ -91,49 +92,40 @@
return found
}
+ private fun BeyondBoundsLayout.LayoutDirection.isForward(): Boolean =
+ when (this) {
+ Before -> false
+ After -> true
+ Above -> reverseLayout
+ Below -> !reverseLayout
+ Left -> when (layoutDirection) {
+ Ltr -> reverseLayout
+ Rtl -> !reverseLayout
+ }
+ Right -> when (layoutDirection) {
+ Ltr -> !reverseLayout
+ Rtl -> reverseLayout
+ }
+ else -> unsupportedDirection()
+ }
+
private fun addNextInterval(
currentInterval: Interval,
direction: BeyondBoundsLayout.LayoutDirection
): Interval {
var start = currentInterval.start
var end = currentInterval.end
- when (direction) {
- Before -> start--
- After -> end++
- Above -> if (reverseLayout) end++ else start--
- Below -> if (reverseLayout) start-- else end++
- Left -> when (layoutDirection) {
- Ltr -> if (reverseLayout) end++ else start--
- Rtl -> if (reverseLayout) start-- else end++
- }
- Right -> when (layoutDirection) {
- Ltr -> if (reverseLayout) start-- else end++
- Rtl -> if (reverseLayout) end++ else start--
- }
- else -> unsupportedDirection()
+ if (direction.isForward()) {
+ end++
+ } else {
+ start--
}
return beyondBoundsInfo.addInterval(start, end)
}
private fun Interval.hasMoreContent(direction: BeyondBoundsLayout.LayoutDirection): Boolean {
- fun hasMoreItemsBefore() = start > 0
- fun hasMoreItemsAfter() = end < state.itemCount - 1
if (direction.isOppositeToOrientation()) return false
- return when (direction) {
- Before -> hasMoreItemsBefore()
- After -> hasMoreItemsAfter()
- Above -> if (reverseLayout) hasMoreItemsAfter() else hasMoreItemsBefore()
- Below -> if (reverseLayout) hasMoreItemsBefore() else hasMoreItemsAfter()
- Left -> when (layoutDirection) {
- Ltr -> if (reverseLayout) hasMoreItemsAfter() else hasMoreItemsBefore()
- Rtl -> if (reverseLayout) hasMoreItemsBefore() else hasMoreItemsAfter()
- }
- Right -> when (layoutDirection) {
- Ltr -> if (reverseLayout) hasMoreItemsBefore() else hasMoreItemsAfter()
- Rtl -> if (reverseLayout) hasMoreItemsAfter() else hasMoreItemsBefore()
- }
- else -> unsupportedDirection()
- }
+ return if (direction.isForward()) end < state.itemCount - 1 else start > 0
}
private fun BeyondBoundsLayout.LayoutDirection.isOppositeToOrientation(): Boolean {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
index 49c2cb8..d848b79 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
@@ -23,6 +23,7 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerInputScope
import androidx.compose.ui.util.fastAny
+import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
@@ -78,10 +79,10 @@
observer: TextDragObserver
) {
coroutineScope {
- launch {
+ launch(start = CoroutineStart.UNDISPATCHED) {
detectPreDragGesturesWithObserver(observer)
}
- launch {
+ launch(start = CoroutineStart.UNDISPATCHED) {
detectDragGesturesWithObserver(observer)
}
}
diff --git a/compose/material/material/api/public_plus_experimental_current.txt b/compose/material/material/api/public_plus_experimental_current.txt
index 7f65e18..0a71de1 100644
--- a/compose/material/material/api/public_plus_experimental_current.txt
+++ b/compose/material/material/api/public_plus_experimental_current.txt
@@ -76,7 +76,7 @@
}
@androidx.compose.material.ExperimentalMaterialApi public final class BottomDrawerState {
- ctor public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+ ctor @Deprecated public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public androidx.compose.material.BottomDrawerValue getCurrentValue();
@@ -96,7 +96,8 @@
}
public static final class BottomDrawerState.Companion {
- method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+ method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(androidx.compose.ui.unit.Density density, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+ method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
}
@androidx.compose.material.ExperimentalMaterialApi public enum BottomDrawerValue {
@@ -129,6 +130,7 @@
public final class BottomSheetScaffoldKt {
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional int floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomSheetState BottomSheetScaffoldState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
+ method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public static androidx.compose.material.BottomSheetState BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.BottomSheetState bottomSheetState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetState rememberBottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
}
@@ -144,7 +146,7 @@
}
@androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState {
- ctor public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
+ ctor @Deprecated public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public androidx.compose.material.BottomSheetValue getCurrentValue();
@@ -162,7 +164,8 @@
}
public static final class BottomSheetState.Companion {
- method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
+ method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
+ method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
}
@androidx.compose.material.ExperimentalMaterialApi public enum BottomSheetValue {
@@ -370,6 +373,7 @@
public final class DrawerKt {
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomDrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomDrawerState BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
method @androidx.compose.runtime.Composable public static void ModalDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.DrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomDrawerState rememberBottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
method @androidx.compose.runtime.Composable public static androidx.compose.material.DrawerState rememberDrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
@@ -528,7 +532,8 @@
public final class ModalBottomSheetKt {
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ModalBottomSheetLayout(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ModalBottomSheetState sheetState, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
+ method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
+ method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHalfExpanded);
method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
@@ -549,7 +554,8 @@
}
public static final class ModalBottomSheetState.Companion {
- method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded);
+ method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
+ method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded);
method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
}
@@ -733,13 +739,13 @@
}
@androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class SwipeProgress<T> {
- ctor public SwipeProgress(T? from, T? to, float fraction);
+ ctor public SwipeProgress(T from, T to, float fraction);
method public float getFraction();
- method public T! getFrom();
- method public T! getTo();
+ method public T getFrom();
+ method public T getTo();
property public final float fraction;
- property public final T! from;
- property public final T! to;
+ property public final T from;
+ property public final T to;
}
public final class SwipeToDismissKt {
@@ -764,9 +770,9 @@
}
@androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
- ctor public SwipeableState(T? initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
- method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public final T! getCurrentValue();
+ ctor public SwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
+ method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public final T getCurrentValue();
method public final float getDirection();
method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
method public final androidx.compose.runtime.State<java.lang.Float> getOverflow();
@@ -775,8 +781,8 @@
method public final boolean isAnimationRunning();
method public final float performDrag(float delta);
method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- property public final T! currentValue;
+ method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ property public final T currentValue;
property @androidx.compose.material.ExperimentalMaterialApi public final float direction;
property public final boolean isAnimationRunning;
property public final androidx.compose.runtime.State<java.lang.Float> offset;
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
index 5e68ba7..274fd8d 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BackdropScaffoldTest.kt
@@ -89,7 +89,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -107,7 +110,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -131,7 +137,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -149,7 +158,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -173,7 +185,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.fillMaxHeight()) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -191,7 +206,10 @@
persistentAppBar = false,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -209,7 +227,10 @@
stickyFrontLayer = false,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -229,7 +250,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -262,7 +286,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -296,7 +323,10 @@
headerHeight = headerHeight,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -334,7 +364,11 @@
)
},
frontLayerContent = {
- Box(Modifier.height(1000.dp).testTag(frontLayer).background(Color.Yellow))
+ Box(
+ Modifier
+ .height(1000.dp)
+ .testTag(frontLayer)
+ .background(Color.Yellow))
}
)
}
@@ -361,7 +395,10 @@
@Test
fun backdropScaffold_animatesAsSideEffect() {
lateinit var scope: CoroutineScope
- val bottomSheetState = ModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
+ val bottomSheetState = ModalBottomSheetState(
+ initialValue = ModalBottomSheetValue.Hidden,
+ density = rule.density
+ )
@Composable
fun BottomSheet(message: String?) {
@@ -483,7 +520,10 @@
frontLayerScrimColor = Color.Red,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -513,7 +553,10 @@
frontLayerScrimColor = Color.Unspecified,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -549,7 +592,10 @@
frontLayerScrimColor = Color.Red,
appBar = { Box(Modifier.height(peekHeight)) },
backLayerContent = { Box(Modifier.height(contentHeight)) },
- frontLayerContent = { Box(Modifier.fillMaxSize().testTag(frontLayer)) }
+ frontLayerContent = { Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)) }
)
}
@@ -582,9 +628,12 @@
backLayerContent = { Box(Modifier.height(contentHeight)) },
frontLayerContent = {
Box(
- Modifier.fillMaxSize().testTag(frontLayer).clickable {
- frontLayerClicks += 1
- }
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)
+ .clickable {
+ frontLayerClicks += 1
+ }
)
}
)
@@ -621,9 +670,12 @@
backLayerContent = { Box(Modifier.height(contentHeight)) },
frontLayerContent = {
Box(
- Modifier.fillMaxSize().testTag(frontLayer).clickable {
- frontLayerClicks += 1
- }
+ Modifier
+ .fillMaxSize()
+ .testTag(frontLayer)
+ .clickable {
+ frontLayerClicks += 1
+ }
)
}
)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt
index 3328ced..d72ea8f 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DrawerTest.kt
@@ -1397,7 +1397,7 @@
fun bottomDrawer_shortSheet_sizeChanges_snapsToNewTarget() {
var size by mutableStateOf(56.dp)
- val state = BottomDrawerState(BottomDrawerValue.Expanded)
+ val state = BottomDrawerState(BottomDrawerValue.Expanded, density = rule.density)
rule.setMaterialContent {
BottomDrawer(
drawerState = state,
@@ -1425,7 +1425,7 @@
@OptIn(ExperimentalMaterialApi::class)
@Test
fun bottomDrawer_shortDrawer_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
- val drawerState = BottomDrawerState(BottomDrawerValue.Closed)
+ val drawerState = BottomDrawerState(BottomDrawerValue.Closed, density = rule.density)
var hasDrawerContent by mutableStateOf(false) // Start out with empty drawer content
lateinit var scope: CoroutineScope
rule.setMaterialContent {
@@ -1461,7 +1461,7 @@
@OptIn(ExperimentalMaterialApi::class)
@Test
fun bottomDrawer_tallDrawer_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
- val drawerState = BottomDrawerState(BottomDrawerValue.Closed)
+ val drawerState = BottomDrawerState(BottomDrawerValue.Closed, density = rule.density)
var hasDrawerContent by mutableStateOf(false) // Start out with empty drawer content
lateinit var scope: CoroutineScope
rule.setContent {
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt
index e4e6e99..15f9365 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetStateTest.kt
@@ -105,8 +105,9 @@
density: Density
) = ModalBottomSheetState(
initialValue,
+ density,
animationSpec,
confirmValueChange,
isSkipHalfExpanded,
- ).apply { swipeableState.density = density }
+ )
}
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
index 86c4206..ec5503d 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
@@ -550,14 +550,20 @@
modifier = Modifier.testTag(topTag),
scrimColor = scrimColor.value,
sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.HalfExpanded),
- content = { Box(
- Modifier
- .fillMaxSize()
- .testTag(contentTag)) },
- sheetContent = { Box(
- Modifier
- .fillMaxSize()
- .testTag(sheetTag)) }
+ content = {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(contentTag)
+ )
+ },
+ sheetContent = {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(sheetTag)
+ )
+ }
)
closeSheet = getString(Strings.CloseSheet)
}
@@ -714,14 +720,20 @@
ModalBottomSheetLayout(
modifier = Modifier.testTag(topTag),
sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.HalfExpanded),
- content = { Box(
- Modifier
- .fillMaxSize()
- .testTag(contentTag)) },
- sheetContent = { Box(
- Modifier
- .fillMaxSize()
- .testTag(sheetTag)) }
+ content = {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(contentTag)
+ )
+ },
+ sheetContent = {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(sheetTag)
+ )
+ }
)
}
@@ -751,10 +763,13 @@
ModalBottomSheetLayout(
modifier = Modifier.testTag(topTag),
sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden),
- content = { Box(
- Modifier
- .fillMaxSize()
- .testTag(contentTag)) },
+ content = {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(contentTag)
+ )
+ },
sheetContent = {
Box(
Modifier
@@ -780,17 +795,23 @@
fun modalBottomSheet_missingAnchors_findsClosest() {
val topTag = "ModalBottomSheetLayout"
var showShortContent by mutableStateOf(false)
- val sheetState = ModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
+ val sheetState = ModalBottomSheetState(
+ initialValue = ModalBottomSheetValue.Hidden,
+ density = rule.density
+ )
lateinit var scope: CoroutineScope
rule.setMaterialContent {
scope = rememberCoroutineScope()
ModalBottomSheetLayout(
modifier = Modifier.testTag(topTag),
sheetState = sheetState,
- content = { Box(
- Modifier
- .fillMaxSize()
- .testTag(contentTag)) },
+ content = {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag(contentTag)
+ )
+ },
sheetContent = {
if (showShortContent) {
Box(
@@ -1140,7 +1161,7 @@
@Test
fun modalBottomSheet_shortSheet_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
- val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden)
+ val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, density = rule.density)
var hasSheetContent by mutableStateOf(false) // Start out with empty sheet content
lateinit var scope: CoroutineScope
rule.setContent {
@@ -1175,7 +1196,7 @@
@Test
fun modalBottomSheet_tallSheet_anchorChangeHandler_previousTargetNotInAnchors_reconciles() {
- val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden)
+ val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, density = rule.density)
var hasSheetContent by mutableStateOf(false) // Start out with empty sheet content
lateinit var scope: CoroutineScope
rule.setContent {
@@ -1214,7 +1235,8 @@
val stateRestorationTester = StateRestorationTester(rule)
// Not backed by state as we don't want changes to cause recompositions
- var sheetState = ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded)
+ var sheetState =
+ ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded, density = rule.density)
var tallSheetContent = true
stateRestorationTester.setContent {
@@ -1232,7 +1254,8 @@
tallSheetContent = false
// Recreate the sheet state so it doesn't have anchors or an offset yet
- sheetState = ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded)
+ sheetState =
+ ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded, density = rule.density)
assertThat(sheetState.swipeableState.anchors).isEmpty()
assertThat(sheetState.swipeableState.offset).isNull()
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableBox.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableBox.kt
deleted file mode 100644
index 6ea5bee..0000000
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableBox.kt
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:OptIn(ExperimentalMaterialApi::class)
-
-package androidx.compose.material.swipeable
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.swipeAnchors
-import androidx.compose.material.swipeableV2
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.unit.dp
-import kotlin.math.roundToInt
-
-@Composable
-internal fun SwipeableBox(
- swipeableState: SwipeableV2State<TestState>,
- orientation: Orientation = Orientation.Horizontal,
- possibleStates: Set<TestState> = setOf(
- TestState.A,
- TestState.B,
- TestState.C
- ),
- enabled: Boolean = true,
- reverseDirection: Boolean = false,
- anchors: Map<TestState, Float>
-) = SwipeableBox(
- swipeableState = swipeableState,
- orientation = orientation,
- possibleStates = possibleStates,
- enabled = enabled,
- reverseDirection = reverseDirection,
- calculateAnchor = { anchor, _ -> anchors[anchor] }
-)
-
-@Composable
-internal fun SwipeableBox(
- swipeableState: SwipeableV2State<TestState>,
- orientation: Orientation = Orientation.Horizontal,
- possibleStates: Set<TestState> = setOf(
- TestState.A,
- TestState.B,
- TestState.C
- ),
- enabled: Boolean = true,
- reverseDirection: Boolean = false,
- calculateAnchor: (anchor: TestState, layoutSize: IntSize) -> Float? = { state, layoutSize ->
- val size = (
- if (orientation == Orientation.Horizontal) layoutSize.width else layoutSize.height
- ).toFloat()
- when (state) {
- TestState.A -> 0f
- TestState.B -> size / 2
- TestState.C -> size
- }
- }
-) = Box(Modifier.fillMaxSize()) {
- Box(
- Modifier
- .requiredSize(swipeableSize)
- .testTag(swipeableTestTag)
- .swipeableV2(
- state = swipeableState,
- orientation = orientation,
- enabled = enabled,
- reverseDirection = reverseDirection
- )
- .swipeAnchors(
- state = swipeableState,
- possibleValues = possibleStates,
- calculateAnchor = calculateAnchor
- )
- .offset {
- val currentOffset = (swipeableState.offset ?: 0f).roundToInt()
- val x = if (orientation == Orientation.Horizontal) currentOffset else 0
- val y = if (orientation == Orientation.Vertical) currentOffset else 0
- IntOffset(x, y)
- }
- .background(Color.Red)
- )
-}
-
-internal const val swipeableTestTag = "swipebox"
-internal val swipeableSize = 200.dp
-
-internal enum class TestState { A, B, C }
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableTestValue.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableTestValue.kt
new file mode 100644
index 0000000..e24c752
--- /dev/null
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableTestValue.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalMaterialApi::class)
+
+package androidx.compose.material.swipeable
+
+import androidx.compose.material.ExperimentalMaterialApi
+
+internal enum class SwipeableTestValue { A, B, C }
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt
index 8e50ab4..3285fcc 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2AnchorTest.kt
@@ -19,27 +19,22 @@
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
-import androidx.compose.material.AnchorChangeHandler
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.SwipeableV2Defaults
+import androidx.compose.material.SwipeableV2Defaults.ReconcileAnimationOnAnchorChangedCallback
import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.fractionalPositionalThreshold
-import androidx.compose.material.rememberSwipeableV2State
-import androidx.compose.material.swipeAnchors
-import androidx.compose.material.swipeable.TestState.A
-import androidx.compose.material.swipeable.TestState.B
-import androidx.compose.material.swipeable.TestState.C
+import androidx.compose.material.swipeable.SwipeableTestValue.A
+import androidx.compose.material.swipeable.SwipeableTestValue.B
+import androidx.compose.material.swipeable.SwipeableTestValue.C
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
@@ -62,107 +57,9 @@
val rule = createComposeRule()
@Test
- fun swipeable_swipeAnchors_updatedInSameFrame() {
- rule.mainClock.autoAdvance = false
-
- var compositionCounter = 0
- lateinit var state: SwipeableV2State<TestState>
-
- rule.setContent {
- state = rememberSwipeableV2State(initialValue = A)
- compositionCounter++
- Box(
- Modifier
- .height(200.dp)
- .swipeAnchors(
- state,
- possibleValues = setOf(A, B, C)
- ) { state, layoutSize ->
- when (state) {
- A -> 0f
- B -> layoutSize.height.toFloat() / 2
- C -> layoutSize.height.toFloat()
- }
- }
- )
- }
- // Verify composed initially but didn't recompose
- assertThat(compositionCounter).isEqualTo(1)
- // Verify that the anchors are present after one composition
- assertThat(state.anchors).containsKey(A)
- assertThat(state.anchors).containsKey(B)
- assertThat(state.anchors).containsKey(C)
- }
-
- @Test
- fun swipeable_swipeAnchors_calculatedCorrectlyFromLayoutSize() {
- lateinit var state: SwipeableV2State<TestState>
-
- fun anchorA() = 0f
- fun anchorB(layoutHeight: Int) = layoutHeight / 2f
- fun anchorC(layoutHeight: Int) = layoutHeight.toFloat()
-
- val swipeableSize = 200.dp
-
- rule.setContent {
- state = rememberSwipeableV2State(initialValue = A)
- Box(
- Modifier
- .requiredHeight(swipeableSize)
- .swipeAnchors(
- state,
- possibleValues = setOf(A, B, C)
- ) { state, layoutSize ->
- when (state) {
- A -> 0f
- B -> anchorB(layoutSize.height)
- C -> anchorC(layoutSize.height)
- }
- }
- )
- }
-
- val expectedHeight = with(rule.density) { swipeableSize.roundToPx() }
- assertThat(state.anchors[A]).isEqualTo(anchorA())
- assertThat(state.anchors[B]).isEqualTo(anchorB(expectedHeight))
- assertThat(state.anchors[C]).isEqualTo(anchorC(expectedHeight))
- }
-
- @Test
- fun swipeable_swipeAnchors_updateOnSizeChange() {
- lateinit var state: SwipeableV2State<TestState>
-
- val firstAnchors = mapOf(A to 0f, B to 100f, C to 200f)
- val secondAnchors = mapOf(B to 300f, C to 600f)
- var anchors = firstAnchors
- var size by mutableStateOf(100)
-
- rule.setContent {
- state = rememberSwipeableV2State(A)
- Box(
- Modifier
- .size(size.dp) // Trigger remeasure when size changes
- .swipeAnchors(
- state,
- possibleValues = setOf(A, B, C),
- calculateAnchor = { state, _ -> anchors[state] }
- )
- )
- }
-
- assertThat(state.anchors).isEqualTo(firstAnchors)
-
- anchors = secondAnchors
- size = 200
- rule.waitForIdle()
-
- assertThat(state.anchors).isEqualTo(secondAnchors)
- }
-
- @Test
fun swipeable_reconcileAnchorChangeHandler_retargetsAnimationWhenOffsetChanged() {
val animationDurationMillis = 2000
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
lateinit var scope: CoroutineScope
val firstAnchors = mapOf(A to 0f, B to 100f, C to 200f)
@@ -177,33 +74,21 @@
SwipeableV2State(
initialValue = A,
animationSpec = tween(animationDurationMillis, easing = LinearEasing),
- positionalThreshold = fractionalPositionalThreshold(0.5f)
+ positionalThreshold = defaultPositionalThreshold(),
+ velocityThreshold = defaultVelocityThreshold()
)
}
scope = rememberCoroutineScope()
val anchorChangeHandler = remember(state, scope) {
- SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler(
- state = state,
- animate = { target, velocity ->
- scope.launch {
- state.animateTo(
- target,
- velocity
- )
- }
- },
- snap = { target -> scope.launch { state.snapTo(target) } }
+ ReconcileAnimationOnAnchorChangedCallback(
+ state,
+ scope
)
}
Box(
Modifier
.size(size.dp) // Trigger anchor recalculation when size changes
- .swipeAnchors(
- state = state,
- possibleValues = setOf(A, B, C),
- anchorChangeHandler = anchorChangeHandler,
- calculateAnchor = { state, _ -> anchors[state] }
- )
+ .onSizeChanged { state.updateAnchors(anchors, anchorChangeHandler) }
)
}
@@ -223,8 +108,11 @@
@Test
fun swipeable_reconcileAnchorChangeHandler_snapsWhenPreviousAnchorRemoved() {
- val state = SwipeableV2State(initialValue = A)
- lateinit var scope: CoroutineScope
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold(),
+ velocityThreshold = defaultVelocityThreshold()
+ )
val firstAnchors = mapOf(A to 0f, B to 100f, C to 200f)
val secondAnchors = mapOf(B to 400f, C to 600f)
@@ -232,25 +120,14 @@
var size by mutableStateOf(100)
rule.setContent {
- scope = rememberCoroutineScope()
+ val scope = rememberCoroutineScope()
val anchorChangeHandler = remember(state, scope) {
- SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler(
- state = state,
- animate = { target, velocity ->
- scope.launch { state.animateTo(target, velocity) }
- },
- snap = { target -> scope.launch { state.snapTo(target) } }
- )
+ ReconcileAnimationOnAnchorChangedCallback(state, scope)
}
Box(
Modifier
.size(size.dp) // Trigger anchor recalculation when size changes
- .swipeAnchors(
- state = state,
- possibleValues = setOf(A, B, C),
- anchorChangeHandler = anchorChangeHandler,
- calculateAnchor = { state, _ -> anchors[state] }
- )
+ .onSizeChanged { state.updateAnchors(anchors, anchorChangeHandler) }
)
}
@@ -265,32 +142,35 @@
@Test
fun swipeable_anchorChangeHandler_calledWithUpdatedAnchorsWhenChanged() {
- val state = SwipeableV2State(initialValue = A)
- val initialSize = 100.dp
- var size: Dp by mutableStateOf(initialSize)
var anchorChangeHandlerInvocationCount = 0
- var actualPreviousAnchors: Map<TestState, Float>? = null
- var actualNewAnchors: Map<TestState, Float>? = null
- val testChangeHandler = AnchorChangeHandler { _, previousAnchors, newAnchors ->
+ var actualPreviousAnchors: Map<SwipeableTestValue, Float>? = null
+ var actualNewAnchors: Map<SwipeableTestValue, Float>? = null
+ val testChangeHandler = AnchorChangedCallback { _, previousAnchors, newAnchors ->
anchorChangeHandlerInvocationCount++
actualPreviousAnchors = previousAnchors
actualNewAnchors = newAnchors
}
- fun calculateAnchor(value: TestState, layoutSize: IntSize) = when (value) {
- A -> 0f
- B -> layoutSize.height / 2f
- C -> layoutSize.height.toFloat()
- }
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold(),
+ velocityThreshold = defaultVelocityThreshold()
+ )
+ val initialSize = 100.dp
+ var size: Dp by mutableStateOf(initialSize)
rule.setContent {
Box(
Modifier
.requiredSize(size) // Trigger anchor recalculation when size changes
- .swipeAnchors(
- state = state,
- possibleValues = setOf(A, B, C),
- anchorChangeHandler = testChangeHandler,
- calculateAnchor = ::calculateAnchor
- )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.height / 2f,
+ C to layoutSize.height.toFloat()
+ ),
+ testChangeHandler
+ )
+ }
)
}
@@ -302,9 +182,9 @@
val sizePx = with(rule.density) { size.roundToPx() }
val layoutSize = IntSize(sizePx, sizePx)
val expectedNewAnchors = mapOf(
- A to calculateAnchor(A, layoutSize),
- B to calculateAnchor(B, layoutSize),
- C to calculateAnchor(C, layoutSize),
+ A to 0f,
+ B to layoutSize.height / 2f,
+ C to layoutSize.height.toFloat()
)
rule.waitForIdle()
@@ -315,64 +195,50 @@
@Test
fun swipeable_anchorChangeHandler_invokedWithPreviousTarget() {
+ var recordedPreviousTargetValue: SwipeableTestValue? = null
+ val testChangeHandler =
+ AnchorChangedCallback<SwipeableTestValue> { previousTarget, _, _ ->
+ recordedPreviousTargetValue = previousTarget
+ }
val state = SwipeableV2State(
initialValue = A,
- positionalThreshold = fractionalPositionalThreshold(0.5f)
+ positionalThreshold = { totalDistance -> totalDistance * 0.5f },
+ velocityThreshold = defaultVelocityThreshold()
)
- var recordedPreviousTargetValue: TestState? = null
- val testChangeHandler = AnchorChangeHandler<TestState> { previousTarget, _, _ ->
- recordedPreviousTargetValue = previousTarget
- }
var anchors = mapOf(
A to 0f,
B to 100f,
C to 200f
)
- var recompose by mutableStateOf(false)
-
- rule.setContent {
- Box(
- key(recompose) {
- Modifier
- .swipeAnchors(
- state = state,
- possibleValues = setOf(A, B, C),
- anchorChangeHandler = testChangeHandler,
- calculateAnchor = { value, _ -> anchors[value] }
- )
- }
- )
- }
+ state.updateAnchors(anchors, testChangeHandler)
assertThat(state.targetValue).isEqualTo(A)
anchors = mapOf(B to 500f)
- recompose = true
- rule.waitForIdle()
+ state.updateAnchors(anchors, testChangeHandler)
assertThat(recordedPreviousTargetValue).isEqualTo(A) // A is not in the anchors anymore, so
// we can be sure that is not the targetValue calculated from the new anchors
}
@Test
fun swipeable_anchorChangeHandler_invokedIfInitialValueNotInInitialAnchors() {
- val state = SwipeableV2State(initialValue = A)
var anchorChangeHandlerInvocationCount = 0
- val testChangeHandler = AnchorChangeHandler<TestState> { _, _, _ ->
+ val testChangeHandler = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
anchorChangeHandlerInvocationCount++
}
- val anchors = mapOf(B to 100f, C to 200f)
-
- rule.setContent {
- Box(
- Modifier
- .swipeAnchors(
- state = state,
- possibleValues = setOf(B, C),
- anchorChangeHandler = testChangeHandler,
- calculateAnchor = { value, _ -> anchors[value] }
- )
- )
- }
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold(),
+ velocityThreshold = defaultVelocityThreshold()
+ )
+ state.updateAnchors(mapOf(B to 100f, C to 200f), testChangeHandler)
assertThat(anchorChangeHandlerInvocationCount).isEqualTo(1)
}
+
+ private fun defaultPositionalThreshold(): (totalDistance: Float) -> Float = with(rule.density) {
+ { 56.dp.toPx() }
+ }
+ private fun defaultVelocityThreshold(): () -> Float = with(rule.density) {
+ { 125.dp.toPx() }
+ }
}
\ No newline at end of file
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt
index 7840ba1..cf2c3f5 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2GestureTest.kt
@@ -16,24 +16,28 @@
package androidx.compose.material.swipeable
-import androidx.compose.animation.core.AnimationSpec
-import androidx.compose.animation.core.LinearEasing
-import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.requiredSize
import androidx.compose.material.AutoTestFrameClock
import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.SwipeableV2Defaults
import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.fixedPositionalThreshold
-import androidx.compose.material.fractionalPositionalThreshold
-import androidx.compose.material.swipeable.TestState.A
-import androidx.compose.material.swipeable.TestState.B
-import androidx.compose.material.swipeable.TestState.C
+import androidx.compose.material.swipeable.SwipeableTestValue.A
+import androidx.compose.material.swipeable.SwipeableTestValue.B
+import androidx.compose.material.swipeable.SwipeableTestValue.C
+import androidx.compose.material.swipeableV2
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.testutils.WithTouchSlop
+import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTouchInput
@@ -43,12 +47,13 @@
import androidx.compose.ui.test.swipeUp
import androidx.compose.ui.test.swipeWithVelocity
import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import kotlin.math.abs
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@@ -64,50 +69,72 @@
@get:Rule
val rule = createComposeRule()
+ private val SwipeableTestTag = "swipebox"
+ private val SwipeableBoxSize = 200.dp
+
@Test
fun swipeable_swipe_horizontal() {
- val state = SwipeableTestState(initialState = A)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = DefaultVelocityThreshold
+ )
val anchors = mapOf(
A to 0f,
B to 250f,
C to 500f
)
+ state.updateAnchors(anchors)
rule.setContent {
CompositionLocalProvider(LocalDensity provides NoOpDensity) {
WithTouchSlop(0f) {
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Horizontal,
- anchors = anchors
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
}
}
assertThat(state.currentValue).isEqualTo(A)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeRight(endX = right / 2) }
rule.waitForIdle()
assertThat(state.currentValue).isEqualTo(B)
assertThat(state.offset).isEqualTo(anchors.getValue(B))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeRight(startX = right / 2, endX = right) }
rule.waitForIdle()
assertThat(state.currentValue).isEqualTo(C)
assertThat(state.offset).isEqualTo(anchors.getValue(C))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeLeft(endX = right / 2) }
rule.waitForIdle()
assertThat(state.currentValue).isEqualTo(B)
assertThat(state.offset).isEqualTo(anchors.getValue(B))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeLeft(startX = right / 2) }
rule.waitForIdle()
@@ -117,48 +144,67 @@
@Test
fun swipeable_swipe_vertical() {
- val state = SwipeableTestState(initialState = A)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = DefaultVelocityThreshold
+ )
val anchors = mapOf(
A to 0f,
B to 250f,
C to 500f
)
+ state.updateAnchors(anchors)
rule.setContent {
CompositionLocalProvider(LocalDensity provides NoOpDensity) {
WithTouchSlop(0f) {
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical,
- anchors = anchors
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
}
}
assertThat(state.currentValue).isEqualTo(A)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(startY = top, endY = bottom / 2) }
rule.waitForIdle()
assertThat(state.currentValue).isEqualTo(B)
assertThat(state.offset).isEqualTo(anchors.getValue(B))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(startY = bottom / 2, endY = bottom) }
rule.waitForIdle()
assertThat(state.currentValue).isEqualTo(C)
assertThat(state.offset).isEqualTo(anchors.getValue(C))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeUp(startY = bottom, endY = bottom / 2) }
rule.waitForIdle()
assertThat(state.currentValue).isEqualTo(B)
assertThat(state.offset).isEqualTo(anchors.getValue(B))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeUp(startY = bottom / 2, endY = top) }
rule.waitForIdle()
@@ -168,29 +214,48 @@
@Test
fun swipeable_swipe_disabled_horizontal() {
- val state = SwipeableTestState(initialState = A)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = DefaultVelocityThreshold
+ )
val anchors = mapOf(
A to 0f,
B to 250f,
C to 500f
)
+ state.updateAnchors(anchors)
rule.setContent {
CompositionLocalProvider(LocalDensity provides NoOpDensity) {
WithTouchSlop(0f) {
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Horizontal,
- anchors = anchors,
- enabled = false
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal,
+ enabled = false
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
}
}
assertThat(state.currentValue).isEqualTo(A)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeRight(startX = left, endX = right) }
rule.waitForIdle()
@@ -200,29 +265,48 @@
@Test
fun swipeable_swipe_disabled_vertical() {
- val state = SwipeableTestState(initialState = A)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = DefaultVelocityThreshold
+ )
val anchors = mapOf(
A to 0f,
B to 250f,
C to 500f
)
+ state.updateAnchors(anchors)
rule.setContent {
CompositionLocalProvider(LocalDensity provides NoOpDensity) {
WithTouchSlop(0f) {
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical,
- anchors = anchors,
- enabled = false
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical,
+ enabled = false
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
}
}
assertThat(state.currentValue).isEqualTo(A)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(startY = top, endY = bottom) }
rule.waitForIdle()
@@ -234,11 +318,40 @@
fun swipeable_positionalThresholds_fractional_targetState() {
val positionalThreshold = 0.5f
val absThreshold = abs(positionalThreshold)
- val state = SwipeableTestState(
- initialState = A,
- positionalThreshold = fractionalPositionalThreshold(positionalThreshold)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = { totalDistance -> totalDistance * positionalThreshold },
+ velocityThreshold = DefaultVelocityThreshold
)
- rule.setContent { SwipeableBox(state) }
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ val anchors = mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ state.updateAnchors(anchors)
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
+ }
val positionOfA = state.anchors.getValue(A)
val positionOfB = state.anchors.getValue(B)
@@ -284,11 +397,40 @@
fun swipeable_positionalThresholds_fractional_negativeThreshold_targetState() {
val positionalThreshold = -0.5f
val absThreshold = abs(positionalThreshold)
- val state = SwipeableTestState(
- initialState = A,
- positionalThreshold = fractionalPositionalThreshold(positionalThreshold)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = { totalDistance -> totalDistance * positionalThreshold },
+ velocityThreshold = DefaultVelocityThreshold
)
- rule.setContent { SwipeableBox(state) }
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ val anchors = mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ state.updateAnchors(anchors)
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
+ }
val positionOfA = state.anchors.getValue(A)
val positionOfB = state.anchors.getValue(B)
@@ -333,12 +475,42 @@
@Test
fun swipeable_positionalThresholds_fixed_targetState() {
val positionalThreshold = 56.dp
- val absThreshold = with(rule.density) { abs(positionalThreshold.toPx()) }
- val state = SwipeableTestState(
- initialState = A,
- positionalThreshold = fixedPositionalThreshold(positionalThreshold)
+ val positionalThresholdPx = with(rule.density) { positionalThreshold.toPx() }
+ val absThreshold = abs(positionalThresholdPx)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = { positionalThresholdPx },
+ velocityThreshold = DefaultVelocityThreshold
)
- rule.setContent { SwipeableBox(state) }
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ val anchors = mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ state.updateAnchors(anchors)
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
+ }
val initialOffset = state.requireOffset()
@@ -386,12 +558,42 @@
@Test
fun swipeable_positionalThresholds_fixed_negativeThreshold_targetState() {
val positionalThreshold = (-56).dp
- val absThreshold = with(rule.density) { abs(positionalThreshold.toPx()) }
- val state = SwipeableTestState(
- initialState = A,
- positionalThreshold = fixedPositionalThreshold(positionalThreshold)
+ val positionalThresholdPx = with(rule.density) { positionalThreshold.toPx() }
+ val absThreshold = abs(positionalThresholdPx)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = { positionalThresholdPx },
+ velocityThreshold = DefaultVelocityThreshold
)
- rule.setContent { SwipeableBox(state) }
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ val anchors = mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ state.updateAnchors(anchors)
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
+ }
val initialOffset = state.requireOffset()
@@ -441,14 +643,17 @@
runBlocking(AutoTestFrameClock()) {
val velocity = 100.dp
val velocityPx = with(rule.density) { velocity.toPx() }
- val state = SwipeableTestState(
- initialState = A,
- anchors = mapOf(
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = { velocityPx / 2f }
+ )
+ state.updateAnchors(
+ mapOf(
A to 0f,
B to 100f,
C to 200f
- ),
- velocityThreshold = velocity / 2
+ )
)
state.dispatchRawDelta(60f)
state.settle(velocityPx)
@@ -461,15 +666,17 @@
runBlocking(AutoTestFrameClock()) {
val velocity = 100.dp
val velocityPx = with(rule.density) { velocity.toPx() }
- val state = SwipeableTestState(
- initialState = A,
- anchors = mapOf(
+ val state = SwipeableV2State(
+ initialValue = A,
+ velocityThreshold = { velocityPx },
+ positionalThreshold = { Float.POSITIVE_INFINITY }
+ )
+ state.updateAnchors(
+ mapOf(
A to 0f,
B to 100f,
C to 200f
- ),
- velocityThreshold = velocity,
- positionalThreshold = { Float.POSITIVE_INFINITY }
+ )
)
state.dispatchRawDelta(60f)
state.settle(velocityPx / 2)
@@ -479,13 +686,42 @@
@Test
fun swipeable_velocityThreshold_swipe_velocityHigherThanThreshold_advances() {
val velocityThreshold = 100.dp
- val state = SwipeableTestState(
- initialState = A,
- velocityThreshold = velocityThreshold
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = { with(rule.density) { velocityThreshold.toPx() } }
)
- rule.setContent { SwipeableBox(state) }
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ val anchors = mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ state.updateAnchors(anchors)
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
+ }
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput {
swipeWithVelocity(
start = Offset(left, 0f),
@@ -501,14 +737,42 @@
@Test
fun swipeable_velocityThreshold_swipe_velocityLowerThanThreshold_doesntAdvance() {
val velocityThreshold = 100.dp
- val state = SwipeableTestState(
- initialState = A,
- velocityThreshold = velocityThreshold,
+ val state = SwipeableV2State(
+ initialValue = A,
+ velocityThreshold = { with(rule.density) { velocityThreshold.toPx() } },
positionalThreshold = { Float.POSITIVE_INFINITY }
)
- rule.setContent { SwipeableBox(state) }
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ val anchors = mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ state.updateAnchors(anchors)
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
+ }
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput {
swipeWithVelocity(
start = Offset(left, 0f),
@@ -527,23 +791,38 @@
A to 0f,
C to 500f
)
- val state = SwipeableTestState(
- initialState = A,
- velocityThreshold = 0.dp
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = DefaultPositionalThreshold,
+ velocityThreshold = { 0f }
)
+ state.updateAnchors(anchors)
rule.setContent {
- SwipeableBox(
- state,
- calculateAnchor = { state, _ ->
- anchors[state]
- }
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
val overdrag = 100f
val maxBound = state.anchors.getValue(C)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput {
down(Offset(0f, 0f))
moveBy(Offset(x = maxBound + overdrag, y = 0f))
@@ -562,30 +841,40 @@
@Test
fun swipeable_animationCancelledByDrag_resetsTargetValueToClosest() {
rule.mainClock.autoAdvance = false
- val animationDurationMillis = 500
- val offsetAtB = animationDurationMillis / 2f
- val offsetAtC = animationDurationMillis.toFloat()
val anchors = mapOf(
A to 0f,
- B to offsetAtB,
- C to offsetAtC
+ B to 250f,
+ C to 500f
)
- val state = SwipeableTestState(
- initialState = A,
- animationSpec = tween(animationDurationMillis, easing = LinearEasing),
- positionalThreshold = fractionalPositionalThreshold(0.5f)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = { totalDistance -> totalDistance * 0.5f },
+ velocityThreshold = DefaultVelocityThreshold
)
+ state.updateAnchors(anchors)
lateinit var scope: CoroutineScope
rule.setContent {
WithTouchSlop(touchSlop = 0f) {
scope = rememberCoroutineScope()
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Horizontal,
- calculateAnchor = { state, _ ->
- anchors[state]
- }
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
}
@@ -595,11 +884,11 @@
scope.launch { state.animateTo(C) }
rule.mainClock.advanceTimeUntil {
- state.requireOffset() > abs(state.requireOffset() - offsetAtB)
+ state.requireOffset() > abs(state.requireOffset() - anchors.getValue(B))
} // Advance until our closest anchor is B
assertThat(state.targetValue).isEqualTo(C)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput {
down(Offset.Zero)
}
@@ -607,22 +896,11 @@
assertThat(state.targetValue).isEqualTo(B) // B is the closest now so we should target it
}
- private fun SwipeableTestState(
- initialState: TestState,
- density: Density = rule.density,
- positionalThreshold: Density.(distance: Float) -> Float = { 56.dp.toPx() },
- velocityThreshold: Dp = 125.dp,
- anchors: Map<TestState, Float>? = null,
- animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec
- ) = SwipeableV2State(
- initialValue = initialState,
- positionalThreshold = positionalThreshold,
- velocityThreshold = velocityThreshold,
- animationSpec = animationSpec
- ).apply {
- if (anchors != null) updateAnchors(anchors)
- this.density = density
+ private val DefaultPositionalThreshold: (totalDistance: Float) -> Float = {
+ with(rule.density) { 56.dp.toPx() }
}
+
+ private val DefaultVelocityThreshold: () -> Float = { with(rule.density) { 125.dp.toPx() } }
}
private val NoOpDensity = object : Density {
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
index 5fcdcc9..4bba7ee 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
@@ -20,19 +20,24 @@
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material.SwipeableV2Defaults
import androidx.compose.material.SwipeableV2State
-import androidx.compose.material.fractionalPositionalThreshold
import androidx.compose.material.rememberSwipeableV2State
-import androidx.compose.material.swipeAnchors
-import androidx.compose.material.swipeable.TestState.A
-import androidx.compose.material.swipeable.TestState.B
-import androidx.compose.material.swipeable.TestState.C
+import androidx.compose.material.swipeable.SwipeableTestValue.A
+import androidx.compose.material.swipeable.SwipeableTestValue.B
+import androidx.compose.material.swipeable.SwipeableTestValue.C
+import androidx.compose.material.swipeableV2
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MonotonicFrameClock
+import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -40,18 +45,23 @@
import androidx.compose.runtime.setValue
import androidx.compose.testutils.WithTouchSlop
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.StateRestorationTester
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeDown
import androidx.compose.ui.test.swipeUp
+import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.channels.Channel
@@ -70,19 +80,45 @@
@get:Rule
val rule = createComposeRule()
+ private val SwipeableTestTag = "swipebox"
+ private val SwipeableBoxSize = 200.dp
+
@Test
fun swipeable_state_canSkipStateByFling() {
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
rule.setContent {
state = rememberSwipeableV2State(initialValue = A)
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical,
- possibleStates = setOf(A, B, C)
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown() }
rule.waitForIdle()
@@ -92,39 +128,62 @@
@Test
fun swipeable_targetState_updatedOnSwipe() {
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
rule.setContent {
state = rememberSwipeableV2State(initialValue = A)
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical,
- possibleStates = setOf(A, B, C)
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(endY = bottom * 0.45f) }
rule.waitForIdle()
assertThat(state.targetValue).isEqualTo(B)
// Assert that swipe below threshold upward settles at current state
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeUp(endY = bottom * 0.95f, durationMillis = 1000) }
rule.waitForIdle()
assertThat(state.targetValue).isEqualTo(B)
// Assert that swipe below threshold downward settles at current state
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(endY = bottom * 0.05f) }
rule.waitForIdle()
assertThat(state.targetValue).isEqualTo(B)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(endY = bottom * 0.9f) }
rule.waitForIdle()
assertThat(state.targetValue).isEqualTo(C)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeUp(endY = top * 1.1f) }
rule.waitForIdle()
assertThat(state.targetValue).isEqualTo(A)
@@ -135,22 +194,47 @@
rule.mainClock.autoAdvance = false
val animationDuration = 300
val frameLengthMillis = 16L
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
lateinit var scope: CoroutineScope
rule.setContent {
- state = remember {
+ val velocityThreshold = SwipeableV2Defaults.velocityThreshold
+ state = remember(velocityThreshold) {
SwipeableV2State(
initialValue = A,
animationSpec = tween(animationDuration, easing = LinearEasing),
- positionalThreshold = fractionalPositionalThreshold(0.5f)
+ positionalThreshold = { distance -> distance * 0.5f },
+ velocityThreshold = velocityThreshold
)
}
scope = rememberCoroutineScope()
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical,
- possibleStates = setOf(A, B, C)
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
scope.launch {
@@ -178,14 +262,38 @@
@Test
fun swipeable_progress_matchesSwipePosition() {
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
rule.setContent {
state = rememberSwipeableV2State(initialValue = A)
WithTouchSlop(touchSlop = 0f) {
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
}
@@ -194,7 +302,7 @@
val almostAnchorB = anchorB * 0.9f
var expectedProgress = almostAnchorB / (anchorB - anchorA)
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeDown(endY = almostAnchorB) }
assertThat(state.targetValue).isEqualTo(B)
@@ -203,7 +311,7 @@
val almostAnchorA = anchorA + ((anchorB - anchorA) * 0.1f)
expectedProgress = 1 - (almostAnchorA / (anchorB - anchorA))
- rule.onNodeWithTag(swipeableTestTag)
+ rule.onNodeWithTag(SwipeableTestTag)
.performTouchInput { swipeUp(startY = anchorB, endY = almostAnchorA) }
assertThat(state.targetValue).isEqualTo(A)
@@ -212,13 +320,37 @@
@Test
fun swipeable_snapTo_updatesImmediately() = runBlocking {
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
rule.setContent {
state = rememberSwipeableV2State(initialValue = A)
- SwipeableBox(
- swipeableState = state,
- orientation = Orientation.Vertical
- )
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
state.snapTo(C)
@@ -232,12 +364,14 @@
val initialState = C
val animationSpec = tween<Float>(durationMillis = 1000)
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
lateinit var scope: CoroutineScope
restorationTester.setContent {
state = rememberSwipeableV2State(initialState, animationSpec)
- state.updateAnchors(mapOf(A to 0f, B to 100f, C to 200f))
+ SideEffect {
+ state.updateAnchors(mapOf(A to 0f, B to 100f, C to 200f))
+ }
scope = rememberCoroutineScope()
}
@@ -258,13 +392,40 @@
@Test
fun swipeable_targetState_accessedInInitialComposition() {
- lateinit var targetState: TestState
+ lateinit var targetState: SwipeableTestValue
rule.setContent {
val state = rememberSwipeableV2State(initialValue = B)
LaunchedEffect(state.targetValue) {
targetState = state.targetValue
}
- SwipeableBox(state)
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
assertThat(targetState).isEqualTo(B)
@@ -278,7 +439,34 @@
LaunchedEffect(state.progress) {
progress = state.progress
}
- SwipeableBox(state)
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
assertThat(progress).isEqualTo(1f)
@@ -288,11 +476,38 @@
@Ignore("Todo: Fix differences between tests and real code - this shouldn't work :)")
fun swipeable_requireOffset_accessedInInitialComposition_throws() {
var exception: Throwable? = null
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
var offset: Float? = null
rule.setContent {
state = rememberSwipeableV2State(initialValue = B)
- SwipeableBox(state)
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Horizontal
+ )
+ .onSizeChanged { layoutSize ->
+ state.updateAnchors(
+ mapOf(
+ A to 0f,
+ B to layoutSize.width / 2f,
+ C to layoutSize.width.toFloat()
+ )
+ )
+ }
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
exception = runCatching { offset = state.requireOffset() }.exceptionOrNull()
}
@@ -334,7 +549,7 @@
initialVelocity = 0f
).let { TimeUnit.NANOSECONDS.toMillis(it) }
- lateinit var state: SwipeableV2State<TestState>
+ lateinit var state: SwipeableV2State<SwipeableTestValue>
lateinit var scope: CoroutineScope
rule.setContent {
@@ -343,11 +558,30 @@
initialValue = A,
animationSpec = animationSpec
)
- SwipeableBox(
- state,
- calculateAnchor = { state, _ -> anchors[state] }
- )
+ SideEffect {
+ state.updateAnchors(anchors)
+ }
+ Box(Modifier.fillMaxSize()) {
+ Box(
+ Modifier
+ .requiredSize(SwipeableBoxSize)
+ .testTag(SwipeableTestTag)
+ .swipeableV2(
+ state = state,
+ orientation = Orientation.Vertical
+ )
+ .offset {
+ IntOffset(
+ state
+ .requireOffset()
+ .roundToInt(), 0
+ )
+ }
+ .background(Color.Red)
+ )
+ }
}
+
scope.launch {
state.animateTo(C)
}
@@ -363,34 +597,30 @@
fun swipeable_bounds_minBoundIsSmallestAnchor() {
var minBound = 0f
var maxBound = 500f
- var anchors = mapOf(
- A to minBound,
- B to maxBound / 2,
- C to maxBound
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
)
- val state = SwipeableV2State(initialValue = A)
- var size by mutableStateOf(100.dp)
-
- rule.setContent {
- Box(
- Modifier
- .size(size)
- .swipeAnchors(
- state = state,
- possibleValues = anchors.keys,
- calculateAnchor = { state, _ -> anchors[state] }
- )
+ state.updateAnchors(
+ mapOf(
+ A to minBound,
+ B to maxBound / 2,
+ C to maxBound
)
- }
+ )
+ var size by mutableStateOf(100.dp)
assertThat(state.minOffset).isEqualTo(minBound)
assertThat(state.maxOffset).isEqualTo(maxBound)
minBound *= 3
maxBound *= 10
- anchors = mapOf(
- A to minBound,
- C to maxBound
+ state.updateAnchors(
+ mapOf(
+ A to minBound,
+ C to maxBound
+ )
)
size = 200.dp
rule.waitForIdle()
@@ -401,7 +631,11 @@
@Test
fun swipeable_targetNotInAnchors_animateTo_updatesCurrentValue() {
- val state = SwipeableV2State(initialValue = A)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
+ )
assertThat(state.anchors).isEmpty()
assertThat(state.currentValue).isEqualTo(A)
runBlocking { state.animateTo(B) }
@@ -410,7 +644,11 @@
@Test
fun swipeable_targetNotInAnchors_snapTo_updatesCurrentValue() {
- val state = SwipeableV2State(initialValue = A)
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
+ )
assertThat(state.anchors).isEmpty()
assertThat(state.currentValue).isEqualTo(A)
runBlocking { state.snapTo(B) }
@@ -419,30 +657,54 @@
@Test
fun swipeable_updateAnchors_initialUpdate_initialValueInAnchors_shouldntUpdate() {
- val state = SwipeableV2State(initialValue = A)
+ var anchorChangeHandlerInvoked = false
+ val testAnchorChangeHandler = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+ anchorChangeHandlerInvoked = true
+ }
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
+ )
val anchors = mapOf(A to 200f, C to 300f)
- val shouldInvokeChangeHandler = state.updateAnchors(anchors)
- assertThat(shouldInvokeChangeHandler).isFalse()
+ state.updateAnchors(anchors, testAnchorChangeHandler)
+ assertThat(anchorChangeHandlerInvoked).isFalse()
}
@Test
fun swipeable_updateAnchors_initialUpdate_initialValueNotInAnchors_shouldUpdate() {
- val state = SwipeableV2State(initialValue = A)
+ var anchorChangeHandlerInvoked = false
+ val testAnchorChangedCallback = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+ anchorChangeHandlerInvoked = true
+ }
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
+ )
val anchors = mapOf(B to 200f, C to 300f)
- val shouldInvokeChangeHandler = state.updateAnchors(anchors)
- assertThat(shouldInvokeChangeHandler).isTrue()
+ state.updateAnchors(anchors, testAnchorChangedCallback)
+ assertThat(anchorChangeHandlerInvoked).isTrue()
}
@Test
fun swipeable_updateAnchors_updateExistingAnchors_shouldUpdate() {
- val state = SwipeableV2State(initialValue = A)
+ var anchorChangeHandlerInvoked = false
+ val testAnchorChangedCallback = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+ anchorChangeHandlerInvoked = true
+ }
+ val state = SwipeableV2State(
+ initialValue = A,
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
+ )
val anchors = mapOf(A to 0f, B to 200f, C to 300f)
- var shouldInvokeChangeHandler = state.updateAnchors(anchors)
- assertThat(shouldInvokeChangeHandler).isFalse()
+ state.updateAnchors(anchors, testAnchorChangedCallback)
+ assertThat(anchorChangeHandlerInvoked).isFalse()
- shouldInvokeChangeHandler = state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f))
- assertThat(shouldInvokeChangeHandler).isTrue()
+ state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f), testAnchorChangedCallback)
+ assertThat(anchorChangeHandlerInvoked).isTrue()
}
@Test
@@ -450,10 +712,20 @@
val clock = HandPumpTestFrameClock()
val animationScope = CoroutineScope(clock)
val animationDuration = 2000
- val state = SwipeableV2State(initialValue = A, animationSpec = tween(animationDuration))
+
+ var anchorChangeHandlerInvoked = false
+ val testAnchorChangedCallback = AnchorChangedCallback<SwipeableTestValue> { _, _, _ ->
+ anchorChangeHandlerInvoked = true
+ }
+ val state = SwipeableV2State(
+ initialValue = A,
+ animationSpec = tween(animationDuration),
+ positionalThreshold = defaultPositionalThreshold,
+ velocityThreshold = defaultVelocityThreshold
+ )
val anchors = mapOf(A to 0f, B to 200f, C to 300f)
- state.updateAnchors(anchors)
+ state.updateAnchors(anchors, testAnchorChangedCallback)
animationScope.launch(start = CoroutineStart.UNDISPATCHED) {
state.animateTo(B)
}
@@ -462,9 +734,9 @@
assertThat(state.isAnimationRunning).isTrue()
val offsetBeforeAnchorUpdate = state.offset
- val shouldInvokeChangeHandler = state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f))
+ state.updateAnchors(mapOf(A to 100f, B to 500f, C to 700f), testAnchorChangedCallback)
assertThat(offsetBeforeAnchorUpdate).isEqualTo(state.offset)
- assertThat(shouldInvokeChangeHandler).isTrue()
+ assertThat(anchorChangeHandlerInvoked).isTrue()
}
private class HandPumpTestFrameClock : MonotonicFrameClock {
@@ -478,4 +750,10 @@
return onFrame(frameCh.receive())
}
}
+
+ private val defaultPositionalThreshold: (totalDistance: Float) -> Float = {
+ with(rule.density) { 56.dp.toPx() }
+ }
+
+ private val defaultVelocityThreshold: () -> Float = { with(rule.density) { 125.dp.toPx() } }
}
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
index d564f3f..93603b9 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
@@ -14,6 +14,7 @@
* limitations under the License.
*/
package androidx.compose.material
+
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Column
@@ -24,7 +25,9 @@
import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.material.BottomSheetValue.Collapsed
import androidx.compose.material.BottomSheetValue.Expanded
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -38,10 +41,12 @@
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.SubcomposeLayout
+import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.collapse
import androidx.compose.ui.semantics.expand
import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.Velocity
@@ -50,6 +55,7 @@
import androidx.compose.ui.util.fastMaxBy
import kotlin.math.roundToInt
import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
/**
@@ -61,6 +67,7 @@
* The bottom sheet is visible, but only showing its peek height.
*/
Collapsed,
+
/**
* The bottom sheet is visible at its maximum height.
*/
@@ -70,9 +77,12 @@
@Deprecated(
message = "This constructor is deprecated. confirmStateChange has been renamed to " +
"confirmValueChange.",
- replaceWith = ReplaceWith("BottomSheetScaffoldState(initialValue, animationSpec, " +
- "confirmStateChange)")
+ replaceWith = ReplaceWith(
+ "BottomSheetScaffoldState(initialValue, animationSpec, " +
+ "confirmStateChange)"
+ )
)
+@Suppress("Deprecation")
@ExperimentalMaterialApi
fun BottomSheetScaffoldState(
initialValue: BottomSheetValue,
@@ -88,20 +98,64 @@
* State of the persistent bottom sheet in [BottomSheetScaffold].
*
* @param initialValue The initial value of the state.
+ * @param density The density that this state can use to convert values to and from dp.
+ * @param animationSpec The default animation that will be used to animate to a new state.
+ * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
+ */
+@Suppress("Deprecation")
+@ExperimentalMaterialApi
+@Stable
+fun BottomSheetState(
+ initialValue: BottomSheetValue,
+ density: Density,
+ animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
+ confirmValueChange: (BottomSheetValue) -> Boolean = { true }
+) = BottomSheetState(initialValue, animationSpec, confirmValueChange).also {
+ it.density = density
+}
+
+/**
+ * State of the persistent bottom sheet in [BottomSheetScaffold].
+ *
+ * @param initialValue The initial value of the state.
* @param animationSpec The default animation that will be used to animate to a new state.
* @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
*/
@ExperimentalMaterialApi
@Stable
-class BottomSheetState(
+class BottomSheetState @Deprecated(
+ "This constructor is deprecated. Density must be provided by the component. " +
+ "Please use the constructor that provides a [Density].",
+ ReplaceWith(
+ """
+ BottomSheetState(
+ initialValue = initialValue,
+ density = LocalDensity.current,
+ animationSpec = animationSpec,
+ confirmValueChange = confirmValueChange
+ )
+ """
+ )
+) constructor(
initialValue: BottomSheetValue,
animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
confirmValueChange: (BottomSheetValue) -> Boolean = { true }
) {
+
internal val swipeableState = SwipeableV2State(
initialValue = initialValue,
animationSpec = animationSpec,
- confirmValueChange = confirmValueChange
+ confirmValueChange = confirmValueChange,
+ positionalThreshold = {
+ with(requireDensity()) {
+ BottomSheetScaffoldPositionalThreshold.toPx()
+ }
+ },
+ velocityThreshold = {
+ with(requireDensity()) {
+ BottomSheetScaffoldVelocityThreshold.toPx()
+ }
+ }
)
val currentValue: BottomSheetValue
@@ -171,12 +225,48 @@
internal val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning
+ internal var density: Density? = null
+ private fun requireDensity() = requireNotNull(density) {
+ "The density on BottomSheetState ($this) was not set. Did you use BottomSheetState with " +
+ "the BottomSheetScaffold composable?"
+ }
+
+ internal val lastVelocity: Float get() = swipeableState.lastVelocity
+
companion object {
+
/**
* The default [Saver] implementation for [BottomSheetState].
*/
fun Saver(
animationSpec: AnimationSpec<Float>,
+ confirmStateChange: (BottomSheetValue) -> Boolean,
+ density: Density
+ ): Saver<BottomSheetState, *> = Saver(
+ save = { it.swipeableState.currentValue },
+ restore = {
+ BottomSheetState(
+ initialValue = it,
+ density = density,
+ animationSpec = animationSpec,
+ confirmValueChange = confirmStateChange
+ )
+ }
+ )
+
+ /**
+ * The default [Saver] implementation for [BottomSheetState].
+ */
+ @Deprecated(
+ message = "This function is deprecated. Please use the overload where Density is" +
+ " provided.",
+ replaceWith = ReplaceWith(
+ "Saver(animationSpec, confirmStateChange, density)"
+ )
+ )
+ @Suppress("Deprecation")
+ fun Saver(
+ animationSpec: AnimationSpec<Float>,
confirmStateChange: (BottomSheetValue) -> Boolean
): Saver<BottomSheetState, *> = Saver(
save = { it.swipeableState.currentValue },
@@ -190,6 +280,7 @@
)
}
}
+
/**
* Create a [BottomSheetState] and [remember] it.
*
@@ -204,20 +295,24 @@
animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
confirmStateChange: (BottomSheetValue) -> Boolean = { true }
): BottomSheetState {
+ val density = LocalDensity.current
return rememberSaveable(
animationSpec,
saver = BottomSheetState.Saver(
animationSpec = animationSpec,
- confirmStateChange = confirmStateChange
+ confirmStateChange = confirmStateChange,
+ density = density
)
) {
BottomSheetState(
initialValue = initialValue,
animationSpec = animationSpec,
- confirmValueChange = confirmStateChange
+ confirmValueChange = confirmStateChange,
+ density = density
)
}
}
+
/**
* State of the [BottomSheetScaffold] composable.
*
@@ -232,6 +327,7 @@
val bottomSheetState: BottomSheetState,
val snackbarHostState: SnackbarHostState
)
+
/**
* Create and [remember] a [BottomSheetScaffoldState].
*
@@ -254,6 +350,7 @@
)
}
}
+
/**
* <a href="https://material.io/components/sheets-bottom#standard-bottom-sheet" class="external" target="_blank">Material Design standard bottom sheet</a>.
*
@@ -329,6 +426,14 @@
contentColor: Color = contentColorFor(backgroundColor),
content: @Composable (PaddingValues) -> Unit
) {
+ // b/278692145 Remove this once deprecated methods without density are removed
+ if (scaffoldState.bottomSheetState.density == null) {
+ val density = LocalDensity.current
+ SideEffect {
+ scaffoldState.bottomSheetState.density = density
+ }
+ }
+
val peekHeightPx = with(LocalDensity.current) { sheetPeekHeight.toPx() }
val child = @Composable {
BottomSheetScaffoldLayout(
@@ -351,14 +456,16 @@
modifier = nestedScroll
.fillMaxWidth()
.requiredHeightIn(min = sheetPeekHeight),
- anchors = { state, sheetSize ->
- when (state) {
- Collapsed -> layoutHeight - peekHeightPx
- Expanded -> if (sheetSize.height == peekHeightPx.roundToInt()) {
- null
- } else {
- layoutHeight - sheetSize.height.toFloat()
- }
+ calculateAnchors = { sheetSize ->
+ val sheetHeight = sheetSize.height.toFloat()
+ val collapsedHeight = layoutHeight - peekHeightPx
+ if (sheetHeight == 0f || sheetHeight == peekHeightPx) {
+ mapOf(Collapsed to collapsedHeight)
+ } else {
+ mapOf(
+ Collapsed to collapsedHeight,
+ Expanded to layoutHeight - sheetHeight
+ )
}
},
sheetBackgroundColor = sheetBackgroundColor,
@@ -402,12 +509,13 @@
}
}
}
+
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun BottomSheet(
state: BottomSheetState,
sheetGesturesEnabled: Boolean,
- anchors: (state: BottomSheetValue, sheetSize: IntSize) -> Float?,
+ calculateAnchors: (sheetSize: IntSize) -> Map<BottomSheetValue, Float>,
sheetShape: Shape,
sheetElevation: Dp,
sheetBackgroundColor: Color,
@@ -416,17 +524,8 @@
content: @Composable ColumnScope.() -> Unit
) {
val scope = rememberCoroutineScope()
- val anchorChangeHandler = remember(state, scope) {
- BottomSheetScaffoldAnchorChangeHandler(
- state = state,
- animateTo = { target -> scope.launch { state.animateTo(target) } },
- snapTo = { target ->
- val didSnapImmediately = state.trySnapTo(target)
- if (!didSnapImmediately) {
- scope.launch { state.snapTo(target) }
- }
- }
- )
+ val anchorChangeCallback = remember(state, scope) {
+ BottomSheetScaffoldAnchorChangeCallback(state, scope)
}
Surface(
modifier
@@ -435,12 +534,12 @@
orientation = Orientation.Vertical,
enabled = sheetGesturesEnabled,
)
- .swipeAnchors(
- state = state.swipeableState,
- possibleValues = setOf(Collapsed, Expanded),
- calculateAnchor = anchors,
- anchorChangeHandler = anchorChangeHandler
- )
+ .onSizeChanged { layoutSize ->
+ state.swipeableState.updateAnchors(
+ newAnchors = calculateAnchors(layoutSize),
+ onAnchorsChanged = anchorChangeCallback
+ )
+ }
.semantics {
// If we don't have anchors yet, or have only one anchor we don't want any
// accessibility actions
@@ -478,12 +577,15 @@
* The default elevation used by [BottomSheetScaffold].
*/
val SheetElevation = 8.dp
+
/**
* The default peek height used by [BottomSheetScaffold].
*/
val SheetPeekHeight = 56.dp
}
+
private enum class BottomSheetScaffoldLayoutSlot { TopBar, Body, Sheet, Fab, Snackbar }
+
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun BottomSheetScaffoldLayout(
@@ -608,13 +710,12 @@
}
@OptIn(ExperimentalMaterialApi::class)
-private fun BottomSheetScaffoldAnchorChangeHandler(
+private fun BottomSheetScaffoldAnchorChangeCallback(
state: BottomSheetState,
- animateTo: (target: BottomSheetValue) -> Unit,
- snapTo: (target: BottomSheetValue) -> Unit,
-) = AnchorChangeHandler<BottomSheetValue> { previousTarget, previousAnchors, newAnchors ->
- val previousTargetOffset = previousAnchors[previousTarget]
- val newTarget = when (previousTarget) {
+ scope: CoroutineScope
+) = AnchorChangedCallback<BottomSheetValue> { prevTarget, prevAnchors, newAnchors ->
+ val previousTargetOffset = prevAnchors[prevTarget]
+ val newTarget = when (prevTarget) {
Collapsed -> Collapsed
Expanded -> if (newAnchors.containsKey(Expanded)) Expanded else Collapsed
}
@@ -622,12 +723,15 @@
if (newTargetOffset != previousTargetOffset) {
if (state.isAnimationRunning) {
// Re-target the animation to the new offset if it changed
- animateTo(newTarget)
+ scope.launch { state.animateTo(newTarget, velocity = state.lastVelocity) }
} else {
// Snap to the new offset value of the target if no animation was running
- snapTo(newTarget)
+ val didSnapSynchronously = state.trySnapTo(newTarget)
+ if (!didSnapSynchronously) scope.launch { state.snapTo(newTarget) }
}
}
}
-private val FabSpacing = 16.dp
\ No newline at end of file
+private val FabSpacing = 16.dp
+private val BottomSheetScaffoldPositionalThreshold = 56.dp
+private val BottomSheetScaffoldVelocityThreshold = 125.dp
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index d5afce0..a47a55e 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -33,7 +33,9 @@
import androidx.compose.material.BottomDrawerValue.Closed
import androidx.compose.material.BottomDrawerValue.Expanded
import androidx.compose.material.BottomDrawerValue.Open
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@@ -49,6 +51,7 @@
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.semantics.contentDescription
@@ -56,6 +59,7 @@
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.paneTitle
import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.LayoutDirection
@@ -121,7 +125,8 @@
initialValue = initialValue,
animationSpec = AnimationSpec,
confirmValueChange = confirmStateChange,
- velocityThreshold = DrawerVelocityThreshold
+ positionalThreshold = { with(requireDensity()) { DrawerPositionalThreshold.toPx() } },
+ velocityThreshold = { with(requireDensity()) { DrawerVelocityThreshold.toPx() } },
)
/**
@@ -229,6 +234,12 @@
internal fun requireOffset(): Float = swipeableState.requireOffset()
+ internal var density: Density? = null
+ private fun requireDensity() = requireNotNull(density) {
+ "The density on DrawerState ($this) was not set. Did you use DrawerState with the Drawer " +
+ "composable?"
+ }
+
companion object {
/**
* The default [Saver] implementation for [DrawerState].
@@ -245,11 +256,43 @@
* State of the [BottomDrawer] composable.
*
* @param initialValue The initial value of the state.
+ * @param density The density that this state can use to convert values to and from dp.
+ * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
+ */
+@Suppress("NotCloseable", "Deprecation")
+@ExperimentalMaterialApi
+fun BottomDrawerState(
+ initialValue: BottomDrawerValue,
+ density: Density,
+ confirmStateChange: (BottomDrawerValue) -> Boolean = { true }
+) = BottomDrawerState(
+ initialValue = initialValue,
+ confirmStateChange = confirmStateChange
+).also {
+ it.density = density
+}
+
+/**
+ * State of the [BottomDrawer] composable.
+ *
+ * @param initialValue The initial value of the state.
* @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.
*/
@Suppress("NotCloseable")
@ExperimentalMaterialApi
-class BottomDrawerState(
+class BottomDrawerState @Deprecated(
+ "This constructor is deprecated. Density must be provided by the component. Please use " +
+ "the constructor that provides a [Density].",
+ ReplaceWith(
+ """
+ BottomDrawerState(
+ initialValue = initialValue,
+ density =,
+ confirmStateChange = confirmStateChange
+ )
+ """
+ )
+) constructor(
initialValue: BottomDrawerValue,
confirmStateChange: (BottomDrawerValue) -> Boolean = { true }
) {
@@ -257,7 +300,8 @@
initialValue = initialValue,
animationSpec = AnimationSpec,
confirmValueChange = confirmStateChange,
- velocityThreshold = DrawerVelocityThreshold
+ positionalThreshold = { with(requireDensity()) { DrawerPositionalThreshold.toPx() } },
+ velocityThreshold = { with(requireDensity()) { DrawerVelocityThreshold.toPx() } },
)
/**
@@ -332,6 +376,16 @@
*
*/
suspend fun expand() = swipeableState.animateTo(Expanded)
+
+ internal suspend fun animateTo(
+ target: BottomDrawerValue,
+ velocity: Float = swipeableState.lastVelocity
+ ) = swipeableState.animateTo(target, velocity)
+
+ internal suspend fun snapTo(target: BottomDrawerValue) = swipeableState.snapTo(target)
+
+ internal fun trySnapTo(target: BottomDrawerValue) = swipeableState.trySnapTo(target)
+
internal fun confirmStateChange(value: BottomDrawerValue): Boolean =
swipeableState.confirmValueChange(value)
@@ -342,10 +396,37 @@
swipeableState
)
+ internal var density: Density? = null
+
+ private fun requireDensity() = requireNotNull(density) {
+ "The density on BottomDrawerState ($this) was not set. Did you use BottomDrawer" +
+ " with the BottomDrawer composable?"
+ }
+
+ internal val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning
+ internal val lastVelocity: Float get() = swipeableState.lastVelocity
+
companion object {
/**
* The default [Saver] implementation for [BottomDrawerState].
*/
+ fun Saver(density: Density, confirmStateChange: (BottomDrawerValue) -> Boolean) =
+ Saver<BottomDrawerState, BottomDrawerValue>(
+ save = { it.swipeableState.currentValue },
+ restore = { BottomDrawerState(it, density, confirmStateChange) }
+ )
+
+ /**
+ * The default [Saver] implementation for [BottomDrawerState].
+ */
+ @Deprecated(
+ message = "This function is deprecated. Please use the overload where Density is" +
+ " provided.",
+ replaceWith = ReplaceWith(
+ "Saver(density, confirmValueChange)"
+ )
+ )
+ @Suppress("Deprecation")
fun Saver(confirmStateChange: (BottomDrawerValue) -> Boolean) =
Saver<BottomDrawerState, BottomDrawerValue>(
save = { it.swipeableState.currentValue },
@@ -382,8 +463,9 @@
initialValue: BottomDrawerValue,
confirmStateChange: (BottomDrawerValue) -> Boolean = { true }
): BottomDrawerState {
- return rememberSaveable(saver = BottomDrawerState.Saver(confirmStateChange)) {
- BottomDrawerState(initialValue, confirmStateChange)
+ val density = LocalDensity.current
+ return rememberSaveable(density, saver = BottomDrawerState.Saver(density, confirmStateChange)) {
+ BottomDrawerState(initialValue, density, confirmStateChange)
}
}
@@ -437,10 +519,16 @@
if (!modalDrawerConstraints.hasBoundedWidth) {
throw IllegalStateException("Drawer shouldn't have infinite width")
}
-
val minValue = -modalDrawerConstraints.maxWidth.toFloat()
val maxValue = 0f
+ val density = LocalDensity.current
+ SideEffect {
+ drawerState.density = density
+ val anchors = mapOf(DrawerValue.Closed to minValue, DrawerValue.Open to maxValue)
+ drawerState.swipeableState.updateAnchors(anchors)
+ }
+
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
Box(
Modifier
@@ -450,15 +538,6 @@
enabled = gesturesEnabled,
reverseDirection = isRtl
)
- .swipeAnchors(
- drawerState.swipeableState,
- possibleValues = setOf(DrawerValue.Closed, DrawerValue.Open)
- ) { value, _ ->
- when (value) {
- DrawerValue.Closed -> minValue
- DrawerValue.Open -> maxValue
- }
- }
) {
Box {
content()
@@ -564,6 +643,13 @@
scrimColor: Color = DrawerDefaults.scrimColor,
content: @Composable () -> Unit
) {
+ // b/278692145 Remove this once deprecated methods without density are removed
+ if (drawerState.density == null) {
+ val density = LocalDensity.current
+ SideEffect {
+ drawerState.density = density
+ }
+ }
val scope = rememberCoroutineScope()
BoxWithConstraints(modifier.fillMaxSize()) {
@@ -607,26 +693,24 @@
visible = drawerState.targetValue != Closed
)
val navigationMenu = getString(Strings.NavigationMenu)
-
+ val anchorChangeCallback = remember(drawerState, scope) {
+ BottomDrawerAnchorChangeCallback(drawerState, scope)
+ }
Surface(
drawerConstraints
- .swipeAnchors(
- drawerState.swipeableState,
- possibleValues = setOf(
- Closed,
- Open,
- Expanded
- ),
- anchorChangeHandler = remember(drawerState, scope) {
- BottomDrawerAnchorChangeHandler(state = drawerState, scope = scope)
+ .onSizeChanged { drawerSize ->
+ val drawerHeight = drawerSize.height.toFloat()
+ val anchors = buildMap {
+ put(Closed, fullHeight)
+ val peekHeight = fullHeight * BottomDrawerOpenFraction
+ if (drawerHeight > peekHeight || isLandscape) {
+ put(Open, peekHeight)
+ }
+ if (drawerHeight > 0f) {
+ put(Expanded, max(0f, fullHeight - drawerHeight))
+ }
}
- ) { value, layoutSize ->
- val drawerHeight = layoutSize.height.toFloat()
- calculateAnchors(
- fullHeight = fullHeight,
- drawerHeight = drawerHeight,
- isLandscape = isLandscape
- )[value]
+ drawerState.swipeableState.updateAnchors(anchors, anchorChangeCallback)
}
.offset {
IntOffset(
@@ -767,6 +851,7 @@
}
private val EndDrawerPadding = 56.dp
+private val DrawerPositionalThreshold = 56.dp
private val DrawerVelocityThreshold = 400.dp
// TODO: b/177571613 this should be a proper decay settling
@@ -832,50 +917,31 @@
}
@OptIn(ExperimentalMaterialApi::class)
-private fun BottomDrawerAnchorChangeHandler(
- state: BottomDrawerState,
- scope: CoroutineScope
-) = AnchorChangeHandler<BottomDrawerValue> { previousTarget, previousAnchors, newAnchors ->
- fun animateTo(target: BottomDrawerValue, velocity: Float) {
- scope.launch {
- state.swipeableState.animateTo(
- target,
- velocity = velocity
- )
- }
- }
+private fun BottomDrawerAnchorChangeCallback(state: BottomDrawerState, scope: CoroutineScope) =
+ AnchorChangedCallback<BottomDrawerValue> { previousTarget, previousAnchors, newAnchors ->
+ val previousTargetOffset = previousAnchors[previousTarget]
+ val newTarget = when (previousTarget) {
+ Closed -> Closed
+ Open, Expanded -> {
+ val hasHalfExpandedState = newAnchors.containsKey(Open)
+ val newTarget = if (hasHalfExpandedState) {
+ Open
+ } else {
+ if (newAnchors.containsKey(Expanded)) Expanded else Closed
+ }
- fun snapTo(target: BottomDrawerValue) {
- val didSnapSynchronously = state.swipeableState.trySnapTo(target)
- if (!didSnapSynchronously) scope.launch {
- state.swipeableState.snapTo(
- target
- )
- }
- }
-
- val previousTargetOffset = previousAnchors[previousTarget]
- val newTarget = when (previousTarget) {
- Closed -> Closed
- Open, Expanded -> {
- val hasHalfExpandedState = newAnchors.containsKey(Open)
- val newTarget = if (hasHalfExpandedState) {
- Open
- } else {
- if (newAnchors.containsKey(Expanded)) Expanded else Closed
+ newTarget
}
-
- newTarget
}
- }
- val newTargetOffset = newAnchors.getValue(newTarget)
- if (newTargetOffset != previousTargetOffset) {
- if (state.swipeableState.isAnimationRunning) {
- // Re-target the animation to the new offset if it changed
- animateTo(newTarget, state.swipeableState.lastVelocity)
- } else {
- // Snap to the new offset value of the target if no animation was running
- snapTo(newTarget)
+ val newTargetOffset = newAnchors.getValue(newTarget)
+ if (newTargetOffset != previousTargetOffset) {
+ if (state.isAnimationRunning) {
+ // Re-target the animation to the new offset if it changed
+ scope.launch { state.animateTo(newTarget, velocity = state.lastVelocity) }
+ } else {
+ // Snap to the new offset value of the target if no animation was running
+ val didSnapSynchronously = state.trySnapTo(newTarget)
+ if (!didSnapSynchronously) scope.launch { state.snapTo(newTarget) }
+ }
}
- }
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
index 5bd062c..5807196 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
@@ -34,7 +34,9 @@
import androidx.compose.material.ModalBottomSheetValue.Expanded
import androidx.compose.material.ModalBottomSheetValue.HalfExpanded
import androidx.compose.material.ModalBottomSheetValue.Hidden
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.remember
@@ -51,6 +53,8 @@
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.collapse
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.dismiss
@@ -65,6 +69,7 @@
import kotlin.math.max
import kotlin.math.roundToInt
import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
/**
@@ -94,6 +99,7 @@
*
* @param initialValue The initial value of the state. <b>Must not be set to
* [ModalBottomSheetValue.HalfExpanded] if [isSkipHalfExpanded] is set to true.</b>
+ * @param density The density that this state can use to convert values to and from dp.
* @param animationSpec The default animation that will be used to animate to a new state.
* @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
* @param isSkipHalfExpanded Whether the half expanded state, if the sheet is tall enough, should
@@ -107,6 +113,53 @@
@Suppress("Deprecation")
fun ModalBottomSheetState(
initialValue: ModalBottomSheetValue,
+ density: Density,
+ animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
+ confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },
+ isSkipHalfExpanded: Boolean = false,
+) = ModalBottomSheetState(
+ initialValue = initialValue,
+ animationSpec = animationSpec,
+ isSkipHalfExpanded = isSkipHalfExpanded,
+ confirmStateChange = confirmValueChange
+).also {
+ it.density = density
+}
+
+/**
+ * State of the [ModalBottomSheetLayout] composable.
+ *
+ * @param initialValue The initial value of the state. <b>Must not be set to
+ * [ModalBottomSheetValue.HalfExpanded] if [isSkipHalfExpanded] is set to true.</b>
+ * @param animationSpec The default animation that will be used to animate to a new state.
+ * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
+ * @param isSkipHalfExpanded Whether the half expanded state, if the sheet is tall enough, should
+ * be skipped. If true, the sheet will always expand to the [Expanded] state and move to the
+ * [Hidden] state when hiding the sheet, either programmatically or by user interaction.
+ * <b>Must not be set to true if the initialValue is [ModalBottomSheetValue.HalfExpanded].</b>
+ * If supplied with [ModalBottomSheetValue.HalfExpanded] for the initialValue, an
+ * [IllegalArgumentException] will be thrown.
+ */
+@ExperimentalMaterialApi
+@Deprecated(
+ "This constructor is deprecated. Density must be provided by the component. " +
+ "Please use the constructor that provides a [Density].",
+ ReplaceWith(
+ """
+ ModalBottomSheetState(
+ initialValue = initialValue,
+ density =,
+ animationSpec = animationSpec,
+ isSkipHalfExpanded = isSkipHalfExpanded,
+ confirmStateChange = confirmValueChange
+ )
+ """
+
+ )
+)
+@Suppress("Deprecation")
+fun ModalBottomSheetState(
+ initialValue: ModalBottomSheetValue,
animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },
isSkipHalfExpanded: Boolean = false
@@ -135,8 +188,10 @@
class ModalBottomSheetState @Deprecated(
message = "This constructor is deprecated. confirmStateChange has been renamed to " +
"confirmValueChange.",
- replaceWith = ReplaceWith("ModalBottomSheetState(" +
- "initialValue, animationSpec, confirmStateChange, isSkipHalfExpanded)")
+ replaceWith = ReplaceWith(
+ "ModalBottomSheetState(" +
+ "initialValue, animationSpec, confirmStateChange, isSkipHalfExpanded)"
+ )
) constructor(
initialValue: ModalBottomSheetValue,
internal val animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec,
@@ -148,8 +203,12 @@
initialValue = initialValue,
animationSpec = animationSpec,
confirmValueChange = confirmStateChange,
- positionalThreshold = PositionalThreshold,
- velocityThreshold = VelocityThreshold
+ positionalThreshold = {
+ with(requireDensity()) {
+ ModalBottomSheetPositionalThreshold.toPx()
+ }
+ },
+ velocityThreshold = { with(requireDensity()) { ModalBottomSheetVelocityThreshold.toPx() } }
)
val currentValue: ModalBottomSheetValue
@@ -170,8 +229,10 @@
@Deprecated(
message = "This constructor is deprecated. confirmStateChange has been renamed to " +
"confirmValueChange.",
- replaceWith = ReplaceWith("ModalBottomSheetState(" +
- "initialValue, animationSpec, confirmStateChange, false)")
+ replaceWith = ReplaceWith(
+ "ModalBottomSheetState(" +
+ "initialValue, animationSpec, confirmStateChange, false)"
+ )
)
@Suppress("Deprecation")
constructor(
@@ -255,6 +316,12 @@
internal val isAnimationRunning: Boolean get() = swipeableState.isAnimationRunning
+ internal var density: Density? = null
+ private fun requireDensity() = requireNotNull(density) {
+ "The density on ModalBottomSheetState ($this) was not set. Did you use " +
+ "ModalBottomSheetState with the ModalBottomSheetLayout composable?"
+ }
+
companion object {
/**
* The default [Saver] implementation for [ModalBottomSheetState].
@@ -265,6 +332,38 @@
animationSpec: AnimationSpec<Float>,
confirmValueChange: (ModalBottomSheetValue) -> Boolean,
skipHalfExpanded: Boolean,
+ density: Density
+ ): Saver<ModalBottomSheetState, *> = Saver(
+ save = { it.currentValue },
+ restore = {
+ ModalBottomSheetState(
+ initialValue = it,
+ density = density,
+ animationSpec = animationSpec,
+ isSkipHalfExpanded = skipHalfExpanded,
+ confirmValueChange = confirmValueChange
+ )
+ }
+ )
+
+ /**
+ * The default [Saver] implementation for [ModalBottomSheetState].
+ * Saves the [currentValue] and recreates a [ModalBottomSheetState] with the saved value as
+ * initial value.
+ */
+ @Deprecated(
+ message = "This function is deprecated. Please use the overload where Density is" +
+ " provided.",
+ replaceWith = ReplaceWith(
+ "Saver(animationSpec, confirmValueChange, density, " +
+ "skipHalfExpanded)"
+ )
+ )
+ @Suppress("Deprecation")
+ fun Saver(
+ animationSpec: AnimationSpec<Float>,
+ confirmValueChange: (ModalBottomSheetValue) -> Boolean,
+ skipHalfExpanded: Boolean,
): Saver<ModalBottomSheetState, *> = Saver(
save = { it.currentValue },
restore = {
@@ -285,9 +384,12 @@
@Deprecated(
message = "This function is deprecated. confirmStateChange has been renamed to " +
"confirmValueChange.",
- replaceWith = ReplaceWith("Saver(animationSpec, confirmStateChange, " +
- "skipHalfExpanded)")
+ replaceWith = ReplaceWith(
+ "Saver(animationSpec, confirmStateChange, " +
+ "skipHalfExpanded)"
+ )
)
+ @Suppress("Deprecation")
fun Saver(
animationSpec: AnimationSpec<Float>,
skipHalfExpanded: Boolean,
@@ -321,19 +423,22 @@
confirmValueChange: (ModalBottomSheetValue) -> Boolean = { true },
skipHalfExpanded: Boolean = false,
): ModalBottomSheetState {
+ val density = LocalDensity.current
// Key the rememberSaveable against the initial value. If it changed we don't want to attempt
// to restore as the restored value could have been saved with a now invalid set of anchors.
// b/152014032
return key(initialValue) {
rememberSaveable(
- initialValue, animationSpec, skipHalfExpanded, confirmValueChange,
+ initialValue, animationSpec, skipHalfExpanded, confirmValueChange, density,
saver = Saver(
+ density = density,
animationSpec = animationSpec,
skipHalfExpanded = skipHalfExpanded,
confirmValueChange = confirmValueChange
)
) {
ModalBottomSheetState(
+ density = density,
initialValue = initialValue,
animationSpec = animationSpec,
isSkipHalfExpanded = skipHalfExpanded,
@@ -359,8 +464,10 @@
@Deprecated(
message = "This function is deprecated. confirmStateChange has been renamed to " +
"confirmValueChange.",
- replaceWith = ReplaceWith("rememberModalBottomSheetState(" +
- "initialValue, animationSpec, confirmStateChange, false)")
+ replaceWith = ReplaceWith(
+ "rememberModalBottomSheetState(" +
+ "initialValue, animationSpec, confirmStateChange, false)"
+ )
)
@Composable
@ExperimentalMaterialApi
@@ -386,8 +493,10 @@
@Deprecated(
message = "This function is deprecated. confirmStateChange has been renamed to " +
"confirmValueChange.",
- replaceWith = ReplaceWith("rememberModalBottomSheetState(" +
- "initialValue, animationSpec, confirmValueChange = confirmStateChange)")
+ replaceWith = ReplaceWith(
+ "rememberModalBottomSheetState(" +
+ "initialValue, animationSpec, confirmValueChange = confirmStateChange)"
+ )
)
@Composable
@ExperimentalMaterialApi
@@ -444,19 +553,17 @@
scrimColor: Color = ModalBottomSheetDefaults.scrimColor,
content: @Composable () -> Unit
) {
+ // b/278692145 Remove this once deprecated methods without density are removed
+ if (sheetState.density == null) {
+ val density = LocalDensity.current
+ SideEffect {
+ sheetState.density = density
+ }
+ }
val scope = rememberCoroutineScope()
val orientation = Orientation.Vertical
- val anchorChangeHandler = remember(sheetState, scope) {
- ModalBottomSheetAnchorChangeHandler(
- state = sheetState,
- animateTo = { target, velocity ->
- scope.launch { sheetState.animateTo(target, velocity = velocity) }
- },
- snapTo = { target ->
- val didSnapSynchronously = sheetState.trySnapTo(target)
- if (!didSnapSynchronously) scope.launch { sheetState.snapTo(target) }
- }
- )
+ val anchorChangeCallback = remember(sheetState, scope) {
+ ModalBottomSheetAnchorChangeCallback(sheetState, scope)
}
BoxWithConstraints(modifier) {
val fullHeight = constraints.maxHeight.toFloat()
@@ -498,23 +605,18 @@
orientation = orientation,
enabled = sheetState.swipeableState.currentValue != Hidden,
)
- .swipeAnchors(
- state = sheetState.swipeableState,
- possibleValues = setOf(Hidden, HalfExpanded, Expanded),
- anchorChangeHandler = anchorChangeHandler
- ) { state, sheetSize ->
- when (state) {
- Hidden -> fullHeight
- HalfExpanded -> when {
- sheetSize.height < fullHeight / 2f -> null
- sheetState.isSkipHalfExpanded -> null
- else -> fullHeight / 2f
+ .onSizeChanged { sheetSize ->
+ val anchors = buildMap {
+ put(Hidden, fullHeight)
+ val halfHeight = fullHeight / 2f
+ if (!sheetState.isSkipHalfExpanded && sheetSize.height > halfHeight) {
+ put(HalfExpanded, halfHeight)
}
-
- Expanded -> if (sheetSize.height != 0) {
- max(0f, fullHeight - sheetSize.height)
- } else null
+ if (sheetSize.height != 0) {
+ put(Expanded, max(0f, fullHeight - sheetSize.height))
+ }
}
+ sheetState.swipeableState.updateAnchors(anchors, anchorChangeCallback)
}
.semantics {
if (sheetState.isVisible) {
@@ -658,18 +760,17 @@
}
@OptIn(ExperimentalMaterialApi::class)
-private fun ModalBottomSheetAnchorChangeHandler(
+private fun ModalBottomSheetAnchorChangeCallback(
state: ModalBottomSheetState,
- animateTo: (target: ModalBottomSheetValue, velocity: Float) -> Unit,
- snapTo: (target: ModalBottomSheetValue) -> Unit,
-) = AnchorChangeHandler<ModalBottomSheetValue> { previousTarget, previousAnchors, newAnchors ->
- val previousTargetOffset = previousAnchors[previousTarget]
- val newTarget = when (previousTarget) {
+ scope: CoroutineScope
+) = AnchorChangedCallback<ModalBottomSheetValue> { prevTarget, prevAnchors, newAnchors ->
+ val previousTargetOffset = prevAnchors[prevTarget]
+ val newTarget = when (prevTarget) {
Hidden -> Hidden
HalfExpanded, Expanded -> {
val hasHalfExpandedState = newAnchors.containsKey(HalfExpanded)
val newTarget = if (hasHalfExpandedState) HalfExpanded
- else if (newAnchors.containsKey(Expanded)) Expanded else Hidden
+ else if (newAnchors.containsKey(Expanded)) Expanded else Hidden
newTarget
}
}
@@ -677,14 +778,15 @@
if (newTargetOffset != previousTargetOffset) {
if (state.isAnimationRunning) {
// Re-target the animation to the new offset if it changed
- animateTo(newTarget, state.lastVelocity)
+ scope.launch { state.animateTo(newTarget, velocity = state.lastVelocity) }
} else {
// Snap to the new offset value of the target if no animation was running
- snapTo(newTarget)
+ val didSnapSynchronously = state.trySnapTo(newTarget)
+ if (!didSnapSynchronously) scope.launch { state.snapTo(newTarget) }
}
}
}
-private val PositionalThreshold: Density.(Float) -> Float = { 56.dp.toPx() }
-private val VelocityThreshold = 125.dp
+private val ModalBottomSheetPositionalThreshold = 56.dp
+private val ModalBottomSheetVelocityThreshold = 125.dp
private val MaxModalBottomSheetWidth = 640.dp
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
index d5d27ae..b467da0 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
@@ -26,6 +26,7 @@
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.offset
+import androidx.compose.material.SwipeableV2State.AnchorChangedCallback
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
@@ -35,21 +36,11 @@
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.LayoutModifier
-import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.MeasureResult
-import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.layout.OnRemeasuredModifier
-import androidx.compose.ui.platform.InspectorInfo
-import androidx.compose.ui.platform.InspectorValueInfo
-import androidx.compose.ui.platform.debugInspectorInfo
-import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import kotlin.math.abs
import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
@@ -90,57 +81,6 @@
)
/**
- * Define anchor points for a given [SwipeableV2State] based on this node's layout size and update
- * the state with them.
- *
- * @param state The associated [SwipeableV2State]
- * @param possibleValues All possible values the [SwipeableV2State] could be in.
- * @param anchorChangeHandler A callback to be invoked when the anchors have changed,
- * `null` by default. Components with custom reconciliation logic should implement this callback,
- * i.e. to re-target an in-progress animation.
- * @param calculateAnchor This method will be invoked to calculate the position of all
- * [possibleValues], given this node's layout size. Return the anchor's offset from the initial
- * anchor, or `null` to indicate that a value does not have an anchor.
- */
-@ExperimentalMaterialApi
-internal fun <T> Modifier.swipeAnchors(
- state: SwipeableV2State<T>,
- possibleValues: Set<T>,
- anchorChangeHandler: AnchorChangeHandler<T>? = null,
- calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,
-) = this.then(SwipeAnchorsModifier(
- onDensityChanged = { state.density = it },
- onSizeChanged = { layoutSize ->
- val previousAnchors = state.anchors
- val newAnchors = mutableMapOf<T, Float>()
- possibleValues.forEach {
- val anchorValue = calculateAnchor(it, layoutSize)
- if (anchorValue != null) {
- newAnchors[it] = anchorValue
- }
- }
- if (previousAnchors != newAnchors) {
- val previousTarget = state.targetValue
- val stateRequiresCleanup = state.updateAnchors(newAnchors)
- if (stateRequiresCleanup) {
- anchorChangeHandler?.onAnchorsChanged(
- previousTarget,
- previousAnchors,
- newAnchors
- )
- }
- }
- },
- inspectorInfo = debugInspectorInfo {
- name = "swipeAnchors"
- properties["state"] = state
- properties["possibleValues"] = possibleValues
- properties["anchorChangeHandler"] = anchorChangeHandler
- properties["calculateAnchor"] = calculateAnchor
- }
-))
-
-/**
* State of the [swipeableV2] modifier.
*
* This contains necessary information about any ongoing swipe or animation and provides methods
@@ -150,12 +90,11 @@
* @param initialValue The initial value of the state.
* @param animationSpec The default animation that will be used to animate to a new state.
* @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.
- * @param positionalThreshold The positional threshold to be used when calculating the target state
- * while a swipe is in progress and when settling after the swipe ends. This is the distance from
- * the start of a transition. It will be, depending on the direction of the interaction, added or
- * subtracted from/to the origin offset. It should always be a positive value. See the
- * [fractionalPositionalThreshold] and [fixedPositionalThreshold] methods.
- * @param velocityThreshold The velocity threshold (in dp per second) that the end velocity has to
+ * @param positionalThreshold The positional threshold, in px, to be used when calculating the
+ * target state while a swipe is in progress and when settling after the swipe ends. This is the
+ * distance from the start of a transition. It will be, depending on the direction of the
+ * interaction, added or subtracted from/to the origin offset. It should always be a positive value.
+ * @param velocityThreshold The velocity threshold (in px per second) that the end velocity has to
* exceed in order to animate to the next state, even if the [positionalThreshold] has not been
* reached.
*/
@@ -163,11 +102,10 @@
@ExperimentalMaterialApi
internal class SwipeableV2State<T>(
initialValue: T,
+ internal val positionalThreshold: (totalDistance: Float) -> Float,
+ internal val velocityThreshold: () -> Float,
internal val animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
- internal val confirmValueChange: (newValue: T) -> Boolean = { true },
- internal val positionalThreshold: Density.(totalDistance: Float) -> Float =
- SwipeableV2Defaults.PositionalThreshold,
- internal val velocityThreshold: Dp = SwipeableV2Defaults.VelocityThreshold,
+ internal val confirmValueChange: (newValue: T) -> Boolean = { true }
) {
private val swipeMutex = InternalMutatorMutex()
@@ -284,28 +222,43 @@
internal var anchors by mutableStateOf(emptyMap<T, Float>())
- internal var density: Density? = null
-
/**
* Update the anchors.
* If the previous set of anchors was empty, attempt to update the offset to match the initial
- * value's anchor.
+ * value's anchor. If the [newAnchors] are different to the existing anchors, or there is no
+ * anchor for the [currentValue], the [onAnchorsChanged] callback will be invoked.
*
- * @return true if the state needs to be adjusted after updating the anchors, e.g. if the
- * initial value is not found in the initial set of anchors. false if no further updates are
- * needed.
+ * <b>If your anchors depend on the size of the layout, updateAnchors should be called in the
+ * layout (placement) phase, e.g. through Modifier.onSizeChanged.</b> This ensures that the
+ * state is set up within the same frame.
+ * For static anchors, or anchors with different data dependencies, updateAnchors is safe to be
+ * called any time, for example from a side effect.
+ *
+ * @param newAnchors The new anchors
+ * @param onAnchorsChanged Optional callback to be invoked if the state needs to be updated
+ * after updating the anchors, for example if the anchor for the [currentValue] has been removed
*/
- internal fun updateAnchors(newAnchors: Map<T, Float>): Boolean {
- val previousAnchorsEmpty = anchors.isEmpty()
- anchors = newAnchors
- val initialValueHasAnchor = if (previousAnchorsEmpty) {
- val initialValue = currentValue
- val initialValueAnchor = anchors[initialValue]
- val initialValueHasAnchor = initialValueAnchor != null
- if (initialValueHasAnchor) trySnapTo(initialValue)
- initialValueHasAnchor
- } else true
- return !initialValueHasAnchor || !previousAnchorsEmpty
+ internal fun updateAnchors(
+ newAnchors: Map<T, Float>,
+ onAnchorsChanged: AnchorChangedCallback<T>? = null
+ ) {
+ if (anchors != newAnchors) {
+ val previousAnchors = anchors
+ val previousTarget = targetValue
+ val previousAnchorsEmpty = anchors.isEmpty()
+ anchors = newAnchors
+
+ val currentValueHasAnchor = anchors[currentValue] != null
+ if (previousAnchorsEmpty && currentValueHasAnchor) {
+ snap(currentValue)
+ } else {
+ onAnchorsChanged?.onAnchorsChanged(
+ previousTargetValue = previousTarget,
+ previousAnchors = previousAnchors,
+ newAnchors = newAnchors
+ )
+ }
+ }
}
/**
@@ -414,8 +367,7 @@
): T {
val currentAnchors = anchors
val currentAnchor = currentAnchors[currentValue]
- val currentDensity = requireDensity()
- val velocityThresholdPx = with(currentDensity) { velocityThreshold.toPx() }
+ val velocityThresholdPx = velocityThreshold()
return if (currentAnchor == offset || currentAnchor == null) {
currentValue
} else if (currentAnchor < offset) {
@@ -425,7 +377,7 @@
} else {
val upper = currentAnchors.closestAnchor(offset, true)
val distance = abs(currentAnchors.getValue(upper) - currentAnchor)
- val relativeThreshold = abs(positionalThreshold(currentDensity, distance))
+ val relativeThreshold = abs(positionalThreshold(distance))
val absoluteThreshold = abs(currentAnchor + relativeThreshold)
if (offset < absoluteThreshold) currentValue else upper
}
@@ -436,7 +388,7 @@
} else {
val lower = currentAnchors.closestAnchor(offset, false)
val distance = abs(currentAnchor - currentAnchors.getValue(lower))
- val relativeThreshold = abs(positionalThreshold(currentDensity, distance))
+ val relativeThreshold = abs(positionalThreshold(distance))
val absoluteThreshold = abs(currentAnchor - relativeThreshold)
if (offset < 0) {
// For negative offsets, larger absolute thresholds are closer to lower anchors
@@ -449,11 +401,6 @@
}
}
- private fun requireDensity() = requireNotNull(density) {
- "SwipeableState did not have a density attached. Are you using Modifier.swipeable with " +
- "this=$this SwipeableState?"
- }
-
private suspend fun swipe(
swipePriority: MutatePriority = MutatePriority.Default,
action: suspend () -> Unit
@@ -487,8 +434,8 @@
fun <T : Any> Saver(
animationSpec: AnimationSpec<Float>,
confirmValueChange: (T) -> Boolean,
- positionalThreshold: Density.(distance: Float) -> Float,
- velocityThreshold: Dp
+ positionalThreshold: (distance: Float) -> Float,
+ velocityThreshold: () -> Float
) = Saver<SwipeableV2State<T>, T>(
save = { it.currentValue },
restore = {
@@ -502,6 +449,34 @@
}
)
}
+
+ /**
+ * Defines a callback that is invoked when the anchors have changed.
+ *
+ * Components with custom reconciliation logic should implement this callback, for example to
+ * re-target an in-progress animation when the anchors change.
+ *
+ * @see SwipeableV2Defaults.ReconcileAnimationOnAnchorChangedCallback for a default
+ * implementation
+ */
+ @ExperimentalMaterialApi
+ fun interface AnchorChangedCallback<T> {
+
+ /**
+ * Callback that is invoked when the anchors have changed, after the [SwipeableV2State] has
+ * been updated with them. Use this hook to re-launch animations or interrupt them if
+ * needed.
+ *
+ * @param previousTargetValue The target value before the anchors were updated
+ * @param previousAnchors The previously set anchors
+ * @param newAnchors The newly set anchors
+ */
+ fun onAnchorsChanged(
+ previousTargetValue: T,
+ previousAnchors: Map<T, Float>,
+ newAnchors: Map<T, Float>,
+ )
+ }
}
/**
@@ -518,49 +493,28 @@
animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
confirmValueChange: (newValue: T) -> Boolean = { true }
): SwipeableV2State<T> {
+ val positionalThreshold = SwipeableV2Defaults.positionalThreshold
+ val velocityThreshold = SwipeableV2Defaults.velocityThreshold
return rememberSaveable(
- initialValue, animationSpec, confirmValueChange,
+ initialValue, animationSpec, confirmValueChange, positionalThreshold, velocityThreshold,
saver = SwipeableV2State.Saver(
animationSpec = animationSpec,
confirmValueChange = confirmValueChange,
- positionalThreshold = SwipeableV2Defaults.PositionalThreshold,
- velocityThreshold = SwipeableV2Defaults.VelocityThreshold
+ positionalThreshold = positionalThreshold,
+ velocityThreshold = velocityThreshold
),
) {
SwipeableV2State(
initialValue = initialValue,
animationSpec = animationSpec,
confirmValueChange = confirmValueChange,
- positionalThreshold = SwipeableV2Defaults.PositionalThreshold,
- velocityThreshold = SwipeableV2Defaults.VelocityThreshold
+ positionalThreshold = positionalThreshold,
+ velocityThreshold = velocityThreshold
)
}
}
/**
- * Expresses a fixed positional threshold of [threshold] dp. This will be the distance from an
- * anchor that needs to be reached for [SwipeableV2State] to settle to the next closest anchor.
- *
- * @see [fractionalPositionalThreshold] for a fractional positional threshold
- */
-@ExperimentalMaterialApi
-internal fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {
- threshold.toPx()
-}
-
-/**
- * Expresses a relative positional threshold of the [fraction] of the distance to the closest anchor
- * in the current direction. This will be the distance from an anchor that needs to be reached for
- * [SwipeableV2State] to settle to the next closest anchor.
- *
- * @see [fixedPositionalThreshold] for a fixed positional threshold
- */
-@ExperimentalMaterialApi
-internal fun fractionalPositionalThreshold(
- fraction: Float
-): Density.(distance: Float) -> Float = { distance -> distance * fraction }
-
-/**
* Contains useful defaults for [swipeableV2] and [SwipeableV2State].
*/
@Stable
@@ -576,102 +530,45 @@
* The default velocity threshold (1.8 dp per millisecond) used by [rememberSwipeableV2State].
*/
@ExperimentalMaterialApi
- val VelocityThreshold: Dp = 125.dp
+ val velocityThreshold: () -> Float
+ @Composable get() = with(LocalDensity.current) { { 125.dp.toPx() } }
/**
* The default positional threshold (56 dp) used by [rememberSwipeableV2State]
*/
@ExperimentalMaterialApi
- val PositionalThreshold: Density.(totalDistance: Float) -> Float =
- fixedPositionalThreshold(56.dp)
+ val positionalThreshold: (totalDistance: Float) -> Float
+ @Composable get() = with(LocalDensity.current) {
+ { 56.dp.toPx() }
+ }
/**
- * A [AnchorChangeHandler] implementation that attempts to reconcile an in-progress animation
+ * A [AnchorChangedCallback] implementation that attempts to reconcile an in-progress animation
* by re-targeting it if necessary or finding the closest new anchor.
* If the previous anchor is not in the new set of anchors, this implementation will snap to the
* closest anchor.
*
* Consider implementing a custom handler for more complex components like sheets.
- * The [animate] and [snap] lambdas hoist the animation and snap logic. Usually these will just
- * delegate to [SwipeableV2State].
- *
- * @param state The [SwipeableV2State] the change handler will read from
- * @param animate A lambda that gets invoked to start an animation to a new target
- * @param snap A lambda that gets invoked to snap to a new target
*/
@ExperimentalMaterialApi
- internal fun <T> ReconcileAnimationOnAnchorChangeHandler(
+ internal fun <T> ReconcileAnimationOnAnchorChangedCallback(
state: SwipeableV2State<T>,
- animate: (target: T, velocity: Float) -> Unit,
- snap: (target: T) -> Unit
- ) = AnchorChangeHandler { previousTarget, previousAnchors, newAnchors ->
- val previousTargetOffset = previousAnchors[previousTarget]
- val newTargetOffset = newAnchors[previousTarget]
- if (previousTargetOffset != newTargetOffset) {
- if (newTargetOffset != null) {
- animate(previousTarget, state.lastVelocity)
- } else {
- snap(newAnchors.closestAnchor(offset = state.requireOffset()))
+ scope: CoroutineScope
+ ) = AnchorChangedCallback<T> { previousTarget, previousAnchors, newAnchors ->
+ val previousTargetOffset = previousAnchors[previousTarget]
+ val newTargetOffset = newAnchors[previousTarget]
+ if (previousTargetOffset != newTargetOffset) {
+ if (newTargetOffset != null) {
+ scope.launch {
+ state.animateTo(previousTarget, state.lastVelocity)
+ }
+ } else {
+ scope.launch {
+ state.snapTo(newAnchors.closestAnchor(offset = state.requireOffset()))
+ }
+ }
}
}
- }
-}
-
-/**
- * Defines a callback that is invoked when the anchors have changed.
- *
- * Components with custom reconciliation logic should implement this callback, for example to
- * re-target an in-progress animation when the anchors change.
- *
- * @see SwipeableV2Defaults.ReconcileAnimationOnAnchorChangeHandler for a default implementation
- */
-@ExperimentalMaterialApi
-internal fun interface AnchorChangeHandler<T> {
-
- /**
- * Callback that is invoked when the anchors have changed, after the [SwipeableV2State] has been
- * updated with them. Use this hook to re-launch animations or interrupt them if needed.
- *
- * @param previousTargetValue The target value before the anchors were updated
- * @param previousAnchors The previously set anchors
- * @param newAnchors The newly set anchors
- */
- fun onAnchorsChanged(
- previousTargetValue: T,
- previousAnchors: Map<T, Float>,
- newAnchors: Map<T, Float>
- )
-}
-
-@Stable
-private class SwipeAnchorsModifier(
- private val onDensityChanged: (density: Density) -> Unit,
- private val onSizeChanged: (layoutSize: IntSize) -> Unit,
- inspectorInfo: InspectorInfo.() -> Unit,
-) : LayoutModifier, OnRemeasuredModifier, InspectorValueInfo(inspectorInfo) {
-
- private var lastDensity: Float = -1f
- private var lastFontScale: Float = -1f
-
- override fun MeasureScope.measure(
- measurable: Measurable,
- constraints: Constraints
- ): MeasureResult {
- if (density != lastDensity || fontScale != lastFontScale) {
- onDensityChanged(Density(density, fontScale))
- lastDensity = density
- lastFontScale = fontScale
- }
- val placeable = measurable.measure(constraints)
- return layout(placeable.width, placeable.height) { placeable.place(0, 0) }
- }
-
- override fun onRemeasured(size: IntSize) {
- onSizeChanged(size)
- }
-
- override fun toString() = "SwipeAnchorsModifierImpl(updateDensity=$onDensityChanged, " +
- "onSizeChanged=$onSizeChanged)"
}
private fun <T> Map<T, Float>.closestAnchor(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
index 0b16d7c..006f13f 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
@@ -107,22 +107,19 @@
// the animation state through this, animating back to the previous value if we don't receive
// a new checked value.
var forceAnimationCheck by remember { mutableStateOf(false) }
- val swipeableState = remember {
+ val switchVelocityThresholdPx = with(LocalDensity.current) { SwitchVelocityThreshold.toPx() }
+ val swipeableState = remember(switchVelocityThresholdPx) {
SwipeableV2State(
initialValue = checked,
- positionalThreshold = SwitchThreshold,
- animationSpec = AnimationSpec
+ animationSpec = AnimationSpec,
+ positionalThreshold = { distance -> distance * SwitchPositionalThreshold },
+ velocityThreshold = { switchVelocityThresholdPx }
)
}
val currentOnCheckedChange by rememberUpdatedState(onCheckedChange)
val currentChecked by rememberUpdatedState(checked)
-
- // Todo: Offer static anchors Modifier.swipeable overload b/265435207
- val density = LocalDensity.current
SideEffect {
- swipeableState.density = density
- val anchors = mapOf(false to minBound, true to maxBound)
- swipeableState.updateAnchors(anchors)
+ swipeableState.updateAnchors(mapOf(false to minBound, true to maxBound))
}
LaunchedEffect(swipeableState) {
snapshotFlow { swipeableState.currentValue }
@@ -419,5 +416,5 @@
}
}
-@OptIn(ExperimentalMaterialApi::class)
-private val SwitchThreshold = fractionalPositionalThreshold(0.7f)
+private const val SwitchPositionalThreshold = 0.7f
+private val SwitchVelocityThreshold = 125.dp
diff --git a/compose/material3/benchmark/build.gradle b/compose/material3/benchmark/build.gradle
index c21a27e..df3e144 100644
--- a/compose/material3/benchmark/build.gradle
+++ b/compose/material3/benchmark/build.gradle
@@ -24,6 +24,7 @@
dependencies {
+ androidTestImplementation(project(":compose:material:material-icons-core"))
androidTestImplementation(project(":compose:material3:material3"))
androidTestImplementation(project(":benchmark:benchmark-junit4"))
androidTestImplementation(project(":compose:runtime:runtime"))
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt
new file mode 100644
index 0000000..d190cbf
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.benchmark
+
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Settings
+import androidx.compose.material3.AssistChip
+import androidx.compose.material3.AssistChipDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.compose.testutils.benchmark.benchmarkFirstDraw
+import androidx.compose.testutils.benchmark.benchmarkFirstLayout
+import androidx.compose.testutils.benchmark.benchmarkFirstMeasure
+import androidx.compose.ui.Modifier
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class ChipBenchmark {
+
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val chipTestCaseFactory = { ChipTestCase() }
+
+ @Test
+ fun first_compose() {
+ benchmarkRule.benchmarkFirstCompose(chipTestCaseFactory)
+ }
+
+ @Test
+ fun chip_measure() {
+ benchmarkRule.benchmarkFirstMeasure(chipTestCaseFactory)
+ }
+
+ @Test
+ fun chip_layout() {
+ benchmarkRule.benchmarkFirstLayout(chipTestCaseFactory)
+ }
+
+ @Test
+ fun chip_draw() {
+ benchmarkRule.benchmarkFirstDraw(chipTestCaseFactory)
+ }
+}
+
+internal class ChipTestCase : LayeredComposeTestCase() {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ override fun MeasuredContent() {
+ AssistChip(
+ onClick = { /* Do something! */ },
+ label = { Text("Assist Chip") },
+ leadingIcon = {
+ Icon(
+ Icons.Filled.Settings,
+ contentDescription = "Localized description",
+ Modifier.size(AssistChipDefaults.IconSize)
+ )
+ }
+ )
+ }
+
+ @Composable
+ override fun ContentWrappers(content: @Composable () -> Unit) {
+ MaterialTheme {
+ content()
+ }
+ }
+}
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DatePickerBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DatePickerBenchmark.kt
new file mode 100644
index 0000000..d047879
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DatePickerBenchmark.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.benchmark
+
+import androidx.compose.material3.DatePicker
+import androidx.compose.material3.DisplayMode
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.rememberDatePickerState
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class DatePickerBenchmark {
+
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val datePickerTestCaseFactory = { DatePickerTestCase() }
+ private val dateInputTestCaseFactory = { DateInputTestCase() }
+
+ @Test
+ fun first_compose_pickerMode() {
+ benchmarkRule.benchmarkFirstCompose(datePickerTestCaseFactory)
+ }
+
+ @Test
+ fun first_compose_inputMode() {
+ benchmarkRule.benchmarkFirstCompose(dateInputTestCaseFactory)
+ }
+
+ @Test
+ fun datePicker_measure() {
+ benchmarkRule.benchmarkFirstMeasure(
+ caseFactory = datePickerTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun dateInput_measure() {
+ benchmarkRule.benchmarkFirstMeasure(
+ caseFactory = dateInputTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun datePicker_layout() {
+ benchmarkRule.benchmarkFirstLayout(
+ caseFactory = datePickerTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun dateInput_layout() {
+ benchmarkRule.benchmarkFirstLayout(
+ caseFactory = dateInputTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun datePicker_draw() {
+ benchmarkRule.benchmarkFirstDraw(
+ caseFactory = datePickerTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun dateInput_draw() {
+ benchmarkRule.benchmarkFirstDraw(
+ caseFactory = dateInputTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+}
+
+/**
+ * A [DatePicker] test case when initiated in its default picker mode.
+ */
+internal class DatePickerTestCase : LayeredComposeTestCase() {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ override fun MeasuredContent() {
+ DatePicker(state = rememberDatePickerState())
+ }
+
+ @Composable
+ override fun ContentWrappers(content: @Composable () -> Unit) {
+ MaterialTheme {
+ content()
+ }
+ }
+}
+
+/**
+ * A [DatePicker] test case when initiated in an input mode.
+ */
+internal class DateInputTestCase : LayeredComposeTestCase() {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ override fun MeasuredContent() {
+ DatePicker(state = rememberDatePickerState(initialDisplayMode = DisplayMode.Input))
+ }
+
+ @Composable
+ override fun ContentWrappers(content: @Composable () -> Unit) {
+ MaterialTheme {
+ content()
+ }
+ }
+}
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DateRangePickerBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DateRangePickerBenchmark.kt
new file mode 100644
index 0000000..d8a46d8
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/DateRangePickerBenchmark.kt
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.benchmark
+
+import androidx.compose.material3.DateRangePicker
+import androidx.compose.material3.DisplayMode
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.rememberDateRangePickerState
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.compose.testutils.benchmark.benchmarkFirstDraw
+import androidx.compose.testutils.benchmark.benchmarkFirstLayout
+import androidx.compose.testutils.benchmark.benchmarkFirstMeasure
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class DateRangePickerBenchmark {
+
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val dateRangePickerTestCaseFactory = { DateRangePickerTestCase() }
+ private val dateRangeInputTestCaseFactory = { DateRangeInputTestCase() }
+
+ @Test
+ fun first_compose_pickerMode() {
+ benchmarkRule.benchmarkFirstCompose(dateRangePickerTestCaseFactory)
+ }
+
+ @Test
+ fun first_compose_inputMode() {
+ benchmarkRule.benchmarkFirstCompose(dateRangeInputTestCaseFactory)
+ }
+
+ @Test
+ fun dateRangePicker_measure() {
+ benchmarkRule.benchmarkFirstMeasure(dateRangePickerTestCaseFactory)
+ }
+
+ @Test
+ fun dateRangeInput_measure() {
+ benchmarkRule.benchmarkFirstMeasure(
+ caseFactory = dateRangeInputTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun dateRangePicker_layout() {
+ benchmarkRule.benchmarkFirstLayout(dateRangePickerTestCaseFactory)
+ }
+
+ @Test
+ fun dateRangeInput_layout() {
+ benchmarkRule.benchmarkFirstLayout(
+ caseFactory = dateRangeInputTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+
+ @Test
+ fun dateRangePicker_draw() {
+ benchmarkRule.benchmarkFirstDraw(dateRangePickerTestCaseFactory)
+ }
+
+ @Test
+ fun dateRangeInput_draw() {
+ benchmarkRule.benchmarkFirstDraw(
+ caseFactory = dateRangeInputTestCaseFactory,
+ allowPendingChanges = true
+ )
+ }
+}
+
+/**
+ * A [DateRangePicker] test case when initiated in its default picker mode.
+ */
+internal class DateRangePickerTestCase : LayeredComposeTestCase() {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ override fun MeasuredContent() {
+ DateRangePicker(state = rememberDateRangePickerState())
+ }
+
+ @Composable
+ override fun ContentWrappers(content: @Composable () -> Unit) {
+ MaterialTheme {
+ content()
+ }
+ }
+}
+
+/**
+ * A [DateRangePicker] test case when initiated in an input mode.
+ */
+internal class DateRangeInputTestCase : LayeredComposeTestCase() {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ override fun MeasuredContent() {
+ DateRangePicker(
+ state = rememberDateRangePickerState(initialDisplayMode = DisplayMode.Input)
+ )
+ }
+
+ @Composable
+ override fun ContentWrappers(content: @Composable () -> Unit) {
+ MaterialTheme {
+ content()
+ }
+ }
+}
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/MaterialBenchmarkExtensions.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/MaterialBenchmarkExtensions.kt
new file mode 100644
index 0000000..5eaa7df
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/MaterialBenchmarkExtensions.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.benchmark
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.testutils.ComposeTestCase
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.assertNoPendingChanges
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.recomposeUntilNoChangesPending
+import androidx.compose.testutils.doFramesUntilNoChangesPending
+import org.junit.Assert
+
+/**
+ * Measures the time of the first draw right after the given test case is added to an already
+ * existing hierarchy.
+ *
+ * @param caseFactory a factory for [LayeredComposeTestCase]
+ * @param allowPendingChanges in case `true`, the benchmark will allow pending changes after the
+ * first draw. Otherwise, an [assertNoPendingChanges] will be called.
+ */
+internal fun ComposeBenchmarkRule.benchmarkFirstDraw(
+ caseFactory: () -> LayeredComposeTestCase,
+ allowPendingChanges: Boolean
+) {
+ runBenchmarkFor(LayeredCaseAdapter.of(caseFactory)) {
+ measureRepeated {
+ runWithTimingDisabled {
+ doFramesUntilNoChangesPending()
+ // Add the content to benchmark
+ getTestCase().addMeasuredContent()
+ recomposeUntilNoChangesPending()
+ requestLayout()
+ measure()
+ layout()
+ drawPrepare()
+ }
+
+ draw()
+
+ runWithTimingDisabled {
+ drawFinish()
+ if (!allowPendingChanges) assertNoPendingChanges()
+ disposeContent()
+ }
+ }
+ }
+}
+
+/**
+ * Measures the time of the first measure right after the given test case is added to an already
+ * existing hierarchy.
+ *
+ * @param caseFactory a factory for [LayeredComposeTestCase]
+ * @param allowPendingChanges in case `true`, the benchmark will allow pending changes after the
+ * first measure. Otherwise, an [assertNoPendingChanges] will be called.
+ */
+internal fun ComposeBenchmarkRule.benchmarkFirstMeasure(
+ caseFactory: () -> LayeredComposeTestCase,
+ allowPendingChanges: Boolean
+) {
+ runBenchmarkFor(LayeredCaseAdapter.of(caseFactory)) {
+ measureRepeated {
+ runWithTimingDisabled {
+ doFramesUntilNoChangesPending()
+ // Add the content to benchmark
+ getTestCase().addMeasuredContent()
+ recomposeUntilNoChangesPending()
+ requestLayout()
+ }
+
+ measure()
+
+ runWithTimingDisabled {
+ if (!allowPendingChanges) assertNoPendingChanges()
+ disposeContent()
+ }
+ }
+ }
+}
+
+/**
+ * Measures the time of the first layout right after the given test case is added to an already
+ * existing hierarchy.
+ *
+ * @param caseFactory a factory for [LayeredComposeTestCase]
+ * @param allowPendingChanges in case `true`, the benchmark will allow pending changes after the
+ * first layout. Otherwise, an [assertNoPendingChanges] will be called.
+ */
+internal fun ComposeBenchmarkRule.benchmarkFirstLayout(
+ caseFactory: () -> LayeredComposeTestCase,
+ allowPendingChanges: Boolean
+) {
+ runBenchmarkFor(LayeredCaseAdapter.of(caseFactory)) {
+ measureRepeated {
+ runWithTimingDisabled {
+ doFramesUntilNoChangesPending()
+ // Add the content to benchmark
+ getTestCase().addMeasuredContent()
+ recomposeUntilNoChangesPending()
+ requestLayout()
+ measure()
+ }
+
+ layout()
+
+ runWithTimingDisabled {
+ if (!allowPendingChanges) assertNoPendingChanges()
+ disposeContent()
+ }
+ }
+ }
+}
+
+private class LayeredCaseAdapter(private val innerCase: LayeredComposeTestCase) : ComposeTestCase {
+
+ companion object {
+ fun of(caseFactory: () -> LayeredComposeTestCase): () -> LayeredCaseAdapter = {
+ LayeredCaseAdapter(caseFactory())
+ }
+ }
+
+ var isComposed by mutableStateOf(false)
+
+ @Composable
+ override fun Content() {
+ innerCase.ContentWrappers {
+ if (isComposed) {
+ innerCase.MeasuredContent()
+ }
+ }
+ }
+
+ fun addMeasuredContent() {
+ Assert.assertTrue(!isComposed)
+ isComposed = true
+ }
+}
+
+private const val MaxAmountOfRecompositions = 10
diff --git a/compose/material3/material3/api/api_lint.ignore b/compose/material3/material3/api/api_lint.ignore
index 21a0335..29ca5ed 100644
--- a/compose/material3/material3/api/api_lint.ignore
+++ b/compose/material3/material3/api/api_lint.ignore
@@ -1,3 +1,11 @@
// Baseline format: 1.0
AutoBoxing: androidx.compose.material3.DatePickerState#setSelectedDateMillis(Long) parameter #0:
Must avoid boxed primitives (`java.lang.Long`)
+
+
+GetterSetterNames: androidx.compose.material3.SheetState#getHasExpandedState():
+ Getter for boolean property `hasExpandedState` is named `getHasExpandedState` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.material3.SheetState#getHasPartiallyExpandedState():
+ Getter for boolean property `hasPartiallyExpandedState` is named `getHasPartiallyExpandedState` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field SnackbarVisuals.withDismissAction:
+ Invalid name for boolean property `withDismissAction`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index 1624518..10979b6 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -37,16 +37,16 @@
*/
implementation(libs.kotlinStdlibCommon)
implementation("androidx.activity:activity-compose:1.5.0")
- implementation("androidx.compose.animation:animation-core:1.4.1")
- implementation("androidx.compose.foundation:foundation-layout:1.4.1")
- implementation("androidx.compose.ui:ui-util:1.4.1")
- api("androidx.compose.foundation:foundation:1.4.1")
- api("androidx.compose.material:material-icons-core:1.4.1")
- api("androidx.compose.material:material-ripple:1.4.1")
- api("androidx.compose.runtime:runtime:1.4.1")
- api("androidx.compose.ui:ui-graphics:1.4.1")
- api("androidx.compose.ui:ui:1.4.1")
- api("androidx.compose.ui:ui-text:1.4.1")
+ implementation("androidx.compose.animation:animation-core:1.4.2")
+ implementation("androidx.compose.foundation:foundation-layout:1.4.2")
+ implementation("androidx.compose.ui:ui-util:1.4.2")
+ api("androidx.compose.foundation:foundation:1.4.2")
+ api("androidx.compose.material:material-icons-core:1.4.2")
+ api("androidx.compose.material:material-ripple:1.4.2")
+ api("androidx.compose.runtime:runtime:1.4.2")
+ api("androidx.compose.ui:ui-graphics:1.4.2")
+ api("androidx.compose.ui:ui:1.4.2")
+ api("androidx.compose.ui:ui-text:1.4.2")
// TODO: remove next 3 dependencies when b/202810604 is fixed
implementation("androidx.savedstate:savedstate-ktx:1.2.1")
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt
index bae18fe..226ffc70 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/BottomSheetSamples.kt
@@ -41,6 +41,7 @@
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
@@ -117,6 +118,8 @@
Text("Hide Bottom Sheet")
}
}
+ var text by remember { mutableStateOf("") }
+ OutlinedTextField(value = text, onValueChange = { text = it })
LazyColumn {
items(50) {
ListItem(
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
index b80c1c4..1abb4ea 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
@@ -22,7 +22,6 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.node.Ref
@@ -152,20 +151,18 @@
val ds = rule.onRoot().getUnclippedBoundsInRoot()
rule.runOnIdleWithDensity {
- assertThat(textPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx()
- .toFloat()
+ assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
)
- assertThat(textPosition.value!!.y).isEqualTo(
- ((listItemHeight.roundToPx() - textSize.value!!.height) / 2f).roundToInt().toFloat()
+ assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - textSize.value!!.height) / 2f
)
- assertThat(trailingPosition.value!!.x).isEqualTo(
- ds.width.roundToPx() - trailingSize.value!!.width -
- expectedEndPadding.roundToPx().toFloat()
+
+ assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+ ds.width.toPx() - trailingSize.value!!.width - expectedEndPadding.toPx()
)
- assertThat(trailingPosition.value!!.y).isEqualTo(
- ((listItemHeight.roundToPx() - trailingSize.value!!.height) / 2f).roundToInt()
- .toFloat()
+ assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
)
}
}
@@ -196,36 +193,35 @@
}
}
rule.runOnIdleWithDensity {
- assertThat(iconPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat()
+ assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
)
- assertThat(iconPosition.value!!.y).isEqualTo(
- ((listItemHeight.roundToPx() - iconSize.value!!.height) / 2f).roundToInt().toFloat()
+ assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - iconSize.value!!.height) / 2f
)
- assertThat(textPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() +
+
+ assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() +
iconSize.value!!.width +
- expectedTextStartPadding.roundToPx().toFloat()
+ expectedTextStartPadding.toPx()
)
- assertThat(textPosition.value!!.y).isEqualTo(
- ((listItemHeight.roundToPx() - textSize.value!!.height) / 2f).roundToInt().toFloat()
+ assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - textSize.value!!.height) / 2f
)
}
}
@Test
fun listItem_twoLine_positioning_noIcon() {
+ val listItemHeight = ListTokens.ListItemTwoLineContainerHeight
val expectedStartPadding = 16.dp
val expectedEndPadding = 24.dp
val textPosition = Ref<Offset>()
- val textBaseline = Ref<Float>()
val textSize = Ref<IntSize>()
val secondaryTextPosition = Ref<Offset>()
- val secondaryTextBaseline = Ref<Float>()
val secondaryTextSize = Ref<IntSize>()
val trailingPosition = Ref<Offset>()
- val trailingBaseline = Ref<Float>()
val trailingSize = Ref<IntSize>()
rule.setMaterialContent(lightColorScheme()) {
Box {
@@ -233,23 +229,19 @@
headlineContent = {
Text(
"Primary text",
- Modifier.saveLayout(textPosition, textSize, textBaseline)
+ Modifier.saveLayout(textPosition, textSize)
)
},
supportingContent = {
Text(
"Secondary text",
- Modifier.saveLayout(
- secondaryTextPosition,
- secondaryTextSize,
- secondaryTextBaseline
- )
+ Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
)
},
trailingContent = {
Text(
"meta",
- Modifier.saveLayout(trailingPosition, trailingSize, trailingBaseline)
+ Modifier.saveLayout(trailingPosition, trailingSize)
)
}
)
@@ -257,29 +249,41 @@
}
val ds = rule.onRoot().getUnclippedBoundsInRoot()
rule.runOnIdleWithDensity {
- assertThat(textPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat()
+ val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
+
+ assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
)
- assertThat(secondaryTextPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat()
+ assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - totalTextHeight) / 2f
)
- assertThat(trailingPosition.value!!.x).isEqualTo(
- ds.width.roundToPx() - trailingSize.value!!.width -
- expectedEndPadding.roundToPx().toFloat()
+
+ assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
+ )
+ assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
+ )
+
+ assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+ ds.width.toPx() - trailingSize.value!!.width -
+ expectedEndPadding.toPx()
+ )
+ assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
)
}
}
@Test
fun listItem_twoLine_positioning_withIcon() {
+ val listItemHeight = ListTokens.ListItemTwoLineContainerHeight
val expectedStartPadding = 16.dp
val expectedContentStartPadding = 16.dp
val textPosition = Ref<Offset>()
- val textBaseline = Ref<Float>()
val textSize = Ref<IntSize>()
val secondaryTextPosition = Ref<Offset>()
- val secondaryTextBaseline = Ref<Float>()
val secondaryTextSize = Ref<IntSize>()
val iconPosition = Ref<Offset>()
val iconSize = Ref<IntSize>()
@@ -289,17 +293,13 @@
headlineContent = {
Text(
"Primary text",
- Modifier.saveLayout(textPosition, textSize, textBaseline)
+ Modifier.saveLayout(textPosition, textSize)
)
},
supportingContent = {
Text(
"Secondary text",
- Modifier.saveLayout(
- secondaryTextPosition,
- secondaryTextSize,
- secondaryTextBaseline
- )
+ Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
)
},
leadingContent = {
@@ -309,17 +309,29 @@
}
}
rule.runOnIdleWithDensity {
- assertThat(textPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() + iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+ val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
+
+ assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
)
- assertThat(secondaryTextPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() +
- iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+ assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - totalTextHeight) / 2f
)
- assertThat(iconPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat()
+
+ assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
+ )
+ assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
+ )
+
+ assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
+ )
+ assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+ (listItemHeight.toPx() - iconSize.value!!.height) / 2f
)
}
}
@@ -331,10 +343,8 @@
val expectedEndPadding = 24.dp
val textPosition = Ref<Offset>()
- val textBaseline = Ref<Float>()
val textSize = Ref<IntSize>()
val secondaryTextPosition = Ref<Offset>()
- val secondaryTextBaseline = Ref<Float>()
val secondaryTextSize = Ref<IntSize>()
val iconPosition = Ref<Offset>()
val iconSize = Ref<IntSize>()
@@ -346,17 +356,13 @@
headlineContent = {
Text(
"Primary text",
- Modifier.saveLayout(textPosition, textSize, textBaseline)
+ Modifier.saveLayout(textPosition, textSize)
)
},
supportingContent = {
Text(
"Very long supporting text which will span two lines",
- Modifier.saveLayout(
- secondaryTextPosition,
- secondaryTextSize,
- secondaryTextBaseline
- )
+ Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
)
},
leadingContent = {
@@ -370,70 +376,64 @@
}
val ds = rule.onRoot().getUnclippedBoundsInRoot()
rule.runOnIdleWithDensity {
- assertThat(textPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() + iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+ // TODO(b/233782301): Test y positions when this is implemented as a 3-line ListItem
+ assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
)
- assertThat(secondaryTextPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() + iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+
+ assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
)
- assertThat(iconPosition.value!!.x).isEqualTo(expectedStartPadding.roundToPx().toFloat())
- assertThat(trailingPosition.value!!.x).isEqualTo(
- ds.width.roundToPx() - trailingSize.value!!.width.toFloat() -
- expectedEndPadding.roundToPx().toFloat()
+
+ assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
+ )
+
+ assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+ ds.width.toPx() - trailingSize.value!!.width -
+ expectedEndPadding.toPx()
)
}
}
@Test
fun listItem_threeLine_positioning_overline_trailingIcon() {
- val expectedTopPadding = 16.dp
+ val expectedTopPadding = 12.dp
val expectedStartPadding = 16.dp
val expectedContentStartPadding = 16.dp
val expectedEndPadding = 24.dp
val textPosition = Ref<Offset>()
- val textBaseline = Ref<Float>()
val textSize = Ref<IntSize>()
val overlineTextPosition = Ref<Offset>()
- val overlineTextBaseline = Ref<Float>()
val overlineTextSize = Ref<IntSize>()
val secondaryTextPosition = Ref<Offset>()
- val secondaryTextBaseline = Ref<Float>()
val secondaryTextSize = Ref<IntSize>()
val iconPosition = Ref<Offset>()
val iconSize = Ref<IntSize>()
val trailingPosition = Ref<Offset>()
val trailingSize = Ref<IntSize>()
- val trailingBaseline = Ref<Float>()
rule.setMaterialContent(lightColorScheme()) {
Box {
ListItem(
overlineContent = {
Text(
"OVERLINE",
- Modifier.saveLayout(
- overlineTextPosition,
- overlineTextSize,
- overlineTextBaseline
- )
+ Modifier.saveLayout(overlineTextPosition, overlineTextSize)
)
},
headlineContent = {
Text(
"Primary text",
- Modifier.saveLayout(textPosition, textSize, textBaseline)
+ Modifier.saveLayout(textPosition, textSize)
)
},
supportingContent = {
Text(
"Secondary text",
- Modifier.saveLayout(
- secondaryTextPosition,
- secondaryTextSize,
- secondaryTextBaseline
- )
+ Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
)
},
leadingContent = {
@@ -446,11 +446,7 @@
trailingContent = {
Text(
"meta",
- Modifier.saveLayout(
- trailingPosition,
- trailingSize,
- trailingBaseline
- )
+ Modifier.saveLayout(trailingPosition, trailingSize)
)
}
)
@@ -459,30 +455,44 @@
val ds = rule.onRoot().getUnclippedBoundsInRoot()
rule.runOnIdleWithDensity {
- assertThat(textPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() +
- iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+ assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
)
- assertThat(secondaryTextPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() +
- iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+ assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+ expectedTopPadding.toPx() + overlineTextSize.value!!.height
)
- assertThat(iconPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat()
+
+ assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
)
- assertThat(trailingPosition.value!!.x).isEqualTo(
- ds.width.roundToPx() - trailingSize.value!!.width -
- expectedEndPadding.roundToPx().toFloat()
+ assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+ expectedTopPadding.toPx() + overlineTextSize.value!!.height +
+ textSize.value!!.height
)
- assertThat(overlineTextPosition.value!!.x).isEqualTo(
- expectedStartPadding.roundToPx().toFloat() +
- iconSize.value!!.width +
- expectedContentStartPadding.roundToPx().toFloat()
+
+ assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx()
)
- assertThat(overlineTextPosition.value!!.y).isEqualTo(
- expectedTopPadding.roundToPx().toFloat()
+ assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+ expectedTopPadding.toPx()
+ )
+
+ assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+ ds.width.toPx() - trailingSize.value!!.width -
+ expectedEndPadding.toPx()
+ )
+ assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+ expectedTopPadding.toPx()
+ )
+
+ assertThat(overlineTextPosition.value!!.x).isWithin(0.5f).of(
+ expectedStartPadding.toPx() + iconSize.value!!.width +
+ expectedContentStartPadding.toPx()
+ )
+ assertThat(overlineTextPosition.value!!.y).isWithin(0.5f).of(
+ expectedTopPadding.toPx()
)
}
}
@@ -492,10 +502,8 @@
private fun Modifier.saveLayout(
coords: Ref<Offset>,
size: Ref<IntSize>,
- baseline: Ref<Float> = Ref()
): Modifier = onGloballyPositioned { coordinates: LayoutCoordinates ->
coords.value = coordinates.localToRoot(Offset.Zero)
- baseline.value = coordinates[FirstBaseline].toFloat() + coords.value!!.y
size.value = coordinates.size
}
}
\ No newline at end of file
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
index 1c5ef84..b2c7357 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
@@ -43,12 +43,14 @@
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
@@ -1493,6 +1495,7 @@
interactionSource: InteractionSource
): State<Dp> {
val interactions = remember { mutableStateListOf<Interaction>() }
+ var lastInteraction by remember { mutableStateOf<Interaction?>(null) }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
@@ -1546,22 +1549,16 @@
val animatable = remember { Animatable(target, Dp.VectorConverter) }
- if (!enabled) {
- // No transition when moving to a disabled state
- LaunchedEffect(target) { animatable.snapTo(target) }
- } else {
- LaunchedEffect(target) {
- val lastInteraction = when (animatable.targetValue) {
- pressedElevation -> PressInteraction.Press(Offset.Zero)
- hoveredElevation -> HoverInteraction.Enter()
- focusedElevation -> FocusInteraction.Focus()
- draggedElevation -> DragInteraction.Start()
- else -> null
- }
+ LaunchedEffect(target) {
+ if (!enabled) {
+ // No transition when moving to a disabled state
+ animatable.snapTo(target)
+ } else {
animatable.animateElevation(
from = lastInteraction, to = interaction, target = target
)
}
+ lastInteraction = interaction
}
return animatable.asState()
@@ -1653,6 +1650,7 @@
interactionSource: InteractionSource
): State<Dp> {
val interactions = remember { mutableStateListOf<Interaction>() }
+ var lastInteraction by remember { mutableStateOf<Interaction?>(null) }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
@@ -1706,22 +1704,16 @@
val animatable = remember { Animatable(target, Dp.VectorConverter) }
- if (!enabled) {
- // No transition when moving to a disabled state
- LaunchedEffect(target) { animatable.snapTo(target) }
- } else {
- LaunchedEffect(target) {
- val lastInteraction = when (animatable.targetValue) {
- pressedElevation -> PressInteraction.Press(Offset.Zero)
- hoveredElevation -> HoverInteraction.Enter()
- focusedElevation -> FocusInteraction.Focus()
- draggedElevation -> DragInteraction.Start()
- else -> null
- }
+ LaunchedEffect(target) {
+ if (!enabled) {
+ // No transition when moving to a disabled state
+ animatable.snapTo(target)
+ } else {
animatable.animateElevation(
from = lastInteraction, to = interaction, target = target
)
}
+ lastInteraction = interaction
}
return animatable.asState()
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
index 114fe42..a770a50 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
@@ -112,12 +112,13 @@
hasOverline = decoratedOverlineContent != null,
hasSupporting = decoratedSupportingContent != null
)
+ val isThreeLine = listItemType == ListItemType.ThreeLine
val decoratedLeadingContent: @Composable (RowScope.() -> Unit)? = leadingContent?.let {
{
LeadingContent(
contentColor = colors.leadingIconColor(enabled = true).value,
- topAlign = listItemType == ListItemType.ThreeLine,
+ topAlign = isThreeLine,
content = it
)
}
@@ -127,7 +128,7 @@
{
TrailingContent(
contentColor = colors.trailingIconColor(enabled = true).value,
- topAlign = listItemType == ListItemType.ThreeLine,
+ topAlign = isThreeLine,
content = it
)
}
@@ -137,19 +138,15 @@
ListItemType.TwoLine -> ListTokens.ListItemTwoLineContainerHeight
else -> ListTokens.ListItemThreeLineContainerHeight // 3
}
+ val verticalPadding = if (isThreeLine) ListItemThreeLineVerticalPadding else
+ ListItemVerticalPadding
val outerPaddingValues =
PaddingValues(
- horizontal = ListItemHorizontalPadding,
- vertical = if (listItemType == ListItemType.ThreeLine)
- ListItemThreeLineVerticalPadding else ListItemVerticalPadding
+ start = ListItemStartPadding,
+ top = verticalPadding,
+ end = ListItemEndPadding,
+ bottom = verticalPadding,
)
- val contentPaddingValues = PaddingValues(
- end = if (listItemType == ListItemType.ThreeLine) ContentEndPadding else 0.dp
- )
- val columnArrangement = if (listItemType == ListItemType.ThreeLine)
- Arrangement.Top else Arrangement.Center
- val boxAlignment = if (listItemType == ListItemType.ThreeLine)
- Alignment.Top else CenterVertically
ListItem(
modifier = modifier,
@@ -166,9 +163,8 @@
Column(
modifier = Modifier
.weight(1f)
- .padding(contentPaddingValues)
- .align(boxAlignment),
- verticalArrangement = columnArrangement
+ .align(if (isThreeLine) Alignment.Top else CenterVertically),
+ verticalArrangement = if (isThreeLine) Arrangement.Top else Arrangement.Center
) {
if (decoratedOverlineContent != null) {
decoratedOverlineContent()
@@ -249,7 +245,7 @@
content: @Composable () -> Unit,
) = Box(
Modifier
- .padding(horizontal = TrailingHorizontalPadding)
+ .padding(start = TrailingContentStartPadding)
.then(if (!topAlign) Modifier.align(CenterVertically) else Modifier),
) {
ProvideTextStyleFromToken(
@@ -430,17 +426,14 @@
// Container related defaults
// TODO: Make sure these values stay up to date until replaced with tokens.
private val ListItemVerticalPadding = 8.dp
-private val ListItemThreeLineVerticalPadding = 16.dp
-private val ListItemHorizontalPadding = 16.dp
+private val ListItemThreeLineVerticalPadding = 12.dp
+private val ListItemStartPadding = 16.dp
+private val ListItemEndPadding = 24.dp
// Icon related defaults.
// TODO: Make sure these values stay up to date until replaced with tokens.
private val LeadingContentEndPadding = 16.dp
-// Content related defaults.
-// TODO: Make sure these values stay up to date until replaced with tokens.
-private val ContentEndPadding = 8.dp
-
// Trailing related defaults.
// TODO: Make sure these values stay up to date until replaced with tokens.
-private val TrailingHorizontalPadding = 8.dp
+private val TrailingContentStartPadding = 16.dp
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.kt
new file mode 100644
index 0000000..ed2aafe2
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetector.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright() 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.runtime.lint
+
+import com.android.tools.lint.detector.api.AnnotationUsageType
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.android.tools.lint.detector.api.UastLintUtils
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UAnnotation
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.USimpleNameReferenceExpression
+
+@Suppress("UnstableApiUsage")
+class AutoboxingStateValuePropertyDetector : Detector(), SourceCodeScanner {
+
+ private val UAnnotation.preferredPropertyName: String?
+ get() = UastLintUtils.getAnnotationStringValue(this, "preferredPropertyName")
+
+ private val UElement.identifier: String?
+ get() = (this as? USimpleNameReferenceExpression)?.identifier
+
+ private val UElement.resolvedName: String?
+ get() = (this as? USimpleNameReferenceExpression)?.resolvedName
+
+ override fun applicableAnnotations(): List<String> {
+ return listOf("androidx.compose.runtime.snapshots.AutoboxingStateValueProperty")
+ }
+
+ override fun visitAnnotationUsage(
+ context: JavaContext,
+ usage: UElement,
+ type: AnnotationUsageType,
+ annotation: UAnnotation,
+ qualifiedName: String,
+ method: PsiMethod?,
+ annotations: List<UAnnotation>,
+ allMemberAnnotations: List<UAnnotation>,
+ allClassAnnotations: List<UAnnotation>,
+ allPackageAnnotations: List<UAnnotation>
+ ) {
+ if (type != AnnotationUsageType.FIELD_REFERENCE) {
+ return
+ }
+
+ val resolvedPropertyName = usage.identifier ?: "<unknown identifier>"
+ val preferredPropertyName = annotation.preferredPropertyName ?: "<unknown replacement>"
+
+ val accessKind = when (usage.resolvedName?.takeWhile { it.isLowerCase() }) {
+ "get" -> "Reading"
+ "set" -> "Assigning"
+ else -> "Accessing"
+ }
+
+ context.report(
+ AutoboxingStateValueProperty,
+ usage,
+ context.getLocation(usage),
+ "$accessKind `$resolvedPropertyName` will cause an autoboxing operation. " +
+ "Use `$preferredPropertyName` to avoid unnecessary allocations.",
+ createPropertyReplacementQuickFix(
+ resolvedPropertyName = resolvedPropertyName,
+ preferredPropertyName = preferredPropertyName
+ )
+ )
+ }
+
+ private fun createPropertyReplacementQuickFix(
+ resolvedPropertyName: String,
+ preferredPropertyName: String
+ ): LintFix {
+ return fix().name("Replace with `$preferredPropertyName`")
+ .replace()
+ .text(resolvedPropertyName)
+ .with(preferredPropertyName)
+ .build()
+ }
+
+ companion object {
+
+ val AutoboxingStateValueProperty = Issue.create(
+ "AutoboxingStateValueProperty",
+ "State access causes value to be autoboxed",
+ "Avoid using the generic value accessor when using a State objects with a " +
+ "specialized types. Usages of the generic value property result in an " +
+ "unnecessary autoboxing operation whenever the state's value is read or " +
+ "written to. Use the specialized value accessor or property delegation to " +
+ "avoid unnecessary allocations.",
+ Category.PERFORMANCE, 3, Severity.WARNING,
+ Implementation(
+ AutoboxingStateValuePropertyDetector::class.java,
+ EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
index edc16ae..bc749d0 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
@@ -30,6 +30,7 @@
override val api = 14
override val minApi = CURRENT_API
override val issues get() = listOf(
+ AutoboxingStateValuePropertyDetector.AutoboxingStateValueProperty,
ComposableCoroutineCreationDetector.CoroutineCreationDuringComposition,
ComposableFlowOperatorDetector.FlowOperatorInvokedInComposition,
ComposableLambdaParameterDetector.ComposableLambdaParameterNaming,
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
new file mode 100644
index 0000000..6f99bf7
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateValuePropertyDetectorTest.kt
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.runtime.lint
+
+import androidx.compose.lint.test.Stubs
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/* ktlint-disable max-line-length */
+@RunWith(JUnit4::class)
+class AutoboxingStateValuePropertyDetectorTest : LintDetectorTest() {
+
+ override fun getDetector(): Detector = AutoboxingStateValuePropertyDetector()
+
+ override fun getIssues(): MutableList<Issue> =
+ mutableListOf(AutoboxingStateValuePropertyDetector.AutoboxingStateValueProperty)
+
+ @Test
+ fun testReadAutoboxingPropertyAsVariableAssignment() {
+ lint().files(
+ AutoboxingStateValuePropertyStub,
+ StateWithAutoboxingPropertyStub,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.sandbox.MutableIntState
+ import androidx.compose.runtime.getValue
+ import androidx.compose.runtime.setValue
+
+ fun valueAssignment() {
+ val state = MutableIntState()
+ val value = state.value
+ }
+ """.trimIndent()
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:9: Warning: Reading value will cause an autoboxing operation. Use intValue to avoid unnecessary allocations. [AutoboxingStateValueProperty]
+ val value = state.value
+ ~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 9: Replace with `intValue`:
+@@ -9 +9
+- val value = state.value
++ val value = state.intValue
+ """
+ )
+ }
+
+ @Test
+ fun testTrivialAssignAutoboxingProperty() {
+ lint().files(
+ AutoboxingStateValuePropertyStub,
+ StateWithAutoboxingPropertyStub,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.sandbox.MutableIntState
+ import androidx.compose.runtime.getValue
+ import androidx.compose.runtime.setValue
+
+ fun valueAssignment() {
+ val state = MutableIntState()
+ state.value = 42
+ }
+ """.trimIndent()
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:9: Warning: Assigning value will cause an autoboxing operation. Use intValue to avoid unnecessary allocations. [AutoboxingStateValueProperty]
+ state.value = 42
+ ~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 9: Replace with `intValue`:
+@@ -9 +9
+- state.value = 42
++ state.intValue = 42
+ """
+ )
+ }
+
+ companion object {
+ private val StateWithAutoboxingPropertyStub = kotlin(
+ """
+ package androidx.compose.runtime.sandbox
+
+ import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
+
+ class MutableIntState {
+
+ @AutoboxingStateValueProperty(
+ preferredPropertyName = "intValue",
+ delegatePackageDirective = "androidx.compose.runtime.sandbox"
+ )
+ var value: Int?
+ get() = intValue
+ set(value) = value?.let { intValue = it }
+
+ var intValue: Int = 0
+ }
+
+ @Suppress("NOTHING_TO_INLINE")
+ inline operator fun MutableIntState.getValue(
+ thisObj: Any?,
+ property: KProperty<*>
+ ): Int = intValue
+
+ @Suppress("NOTHING_TO_INLINE")
+ inline operator fun MutableIntState.setValue(
+ thisObj: Any?,
+ property: KProperty<*>,
+ value: Int
+ ) {
+ intValue = value
+ }
+ """
+ )
+
+ private val AutoboxingStateValuePropertyStub = kotlin(
+ """
+ package androidx.compose.runtime.snapshots
+
+ @Retention(AnnotationRetention.BINARY)
+ @Target(AnnotationTarget.PROPERTY)
+ annotation class AutoboxingStateValueProperty(
+ val preferredPropertyName: String,
+ val delegatePackageDirective: String
+ )
+ """
+ )
+ }
+}
+/* ktlint-enable max-line-length */
\ No newline at end of file
diff --git a/compose/runtime/runtime-livedata/api/current.ignore b/compose/runtime/runtime-livedata/api/current.ignore
new file mode 100644
index 0000000..8e26508
--- /dev/null
+++ b/compose/runtime/runtime-livedata/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.livedata.LiveDataAdapterKt#observeAsState(androidx.lifecycle.LiveData<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.livedata.LiveDataAdapterKt.observeAsState(androidx.lifecycle.LiveData<T> arg1, R initial)
diff --git a/compose/runtime/runtime-livedata/api/current.txt b/compose/runtime/runtime-livedata/api/current.txt
index e004a29..192cf6a 100644
--- a/compose/runtime/runtime-livedata/api/current.txt
+++ b/compose/runtime/runtime-livedata/api/current.txt
@@ -3,7 +3,7 @@
public final class LiveDataAdapterKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> observeAsState(androidx.lifecycle.LiveData<T>);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R initial);
}
}
diff --git a/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt b/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt
index e004a29..192cf6a 100644
--- a/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-livedata/api/public_plus_experimental_current.txt
@@ -3,7 +3,7 @@
public final class LiveDataAdapterKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> observeAsState(androidx.lifecycle.LiveData<T>);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R initial);
}
}
diff --git a/compose/runtime/runtime-livedata/api/restricted_current.ignore b/compose/runtime/runtime-livedata/api/restricted_current.ignore
new file mode 100644
index 0000000..8e26508
--- /dev/null
+++ b/compose/runtime/runtime-livedata/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.livedata.LiveDataAdapterKt#observeAsState(androidx.lifecycle.LiveData<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.livedata.LiveDataAdapterKt.observeAsState(androidx.lifecycle.LiveData<T> arg1, R initial)
diff --git a/compose/runtime/runtime-livedata/api/restricted_current.txt b/compose/runtime/runtime-livedata/api/restricted_current.txt
index e004a29..192cf6a 100644
--- a/compose/runtime/runtime-livedata/api/restricted_current.txt
+++ b/compose/runtime/runtime-livedata/api/restricted_current.txt
@@ -3,7 +3,7 @@
public final class LiveDataAdapterKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> observeAsState(androidx.lifecycle.LiveData<T>);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R initial);
}
}
diff --git a/compose/runtime/runtime-rxjava2/api/current.ignore b/compose/runtime/runtime-rxjava2/api/current.ignore
new file mode 100644
index 0000000..3d56c37
--- /dev/null
+++ b/compose/runtime/runtime-rxjava2/api/current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Flowable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Maybe<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Observable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Single<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava2/api/current.txt b/compose/runtime/runtime-rxjava2/api/current.txt
index fb30f38..ea20020 100644
--- a/compose/runtime/runtime-rxjava2/api/current.txt
+++ b/compose/runtime/runtime-rxjava2/api/current.txt
@@ -2,10 +2,10 @@
package androidx.compose.runtime.rxjava2 {
public final class RxJava2AdapterKt {
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R initial);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
}
diff --git a/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt b/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt
index fb30f38..ea20020 100644
--- a/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-rxjava2/api/public_plus_experimental_current.txt
@@ -2,10 +2,10 @@
package androidx.compose.runtime.rxjava2 {
public final class RxJava2AdapterKt {
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R initial);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
}
diff --git a/compose/runtime/runtime-rxjava2/api/restricted_current.ignore b/compose/runtime/runtime-rxjava2/api/restricted_current.ignore
new file mode 100644
index 0000000..3d56c37
--- /dev/null
+++ b/compose/runtime/runtime-rxjava2/api/restricted_current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Flowable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Maybe<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Observable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava2.RxJava2AdapterKt#subscribeAsState(io.reactivex.Single<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava2.RxJava2AdapterKt.subscribeAsState(io.reactivex.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava2/api/restricted_current.txt b/compose/runtime/runtime-rxjava2/api/restricted_current.txt
index fb30f38..ea20020 100644
--- a/compose/runtime/runtime-rxjava2/api/restricted_current.txt
+++ b/compose/runtime/runtime-rxjava2/api/restricted_current.txt
@@ -2,10 +2,10 @@
package androidx.compose.runtime.rxjava2 {
public final class RxJava2AdapterKt {
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R initial);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
}
diff --git a/compose/runtime/runtime-rxjava3/api/current.ignore b/compose/runtime/runtime-rxjava3/api/current.ignore
new file mode 100644
index 0000000..33b8519
--- /dev/null
+++ b/compose/runtime/runtime-rxjava3/api/current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava3/api/current.txt b/compose/runtime/runtime-rxjava3/api/current.txt
index 1930cc8..aa5ec91 100644
--- a/compose/runtime/runtime-rxjava3/api/current.txt
+++ b/compose/runtime/runtime-rxjava3/api/current.txt
@@ -2,10 +2,10 @@
package androidx.compose.runtime.rxjava3 {
public final class RxJava3AdapterKt {
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R initial);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
}
diff --git a/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt b/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt
index 1930cc8..aa5ec91 100644
--- a/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-rxjava3/api/public_plus_experimental_current.txt
@@ -2,10 +2,10 @@
package androidx.compose.runtime.rxjava3 {
public final class RxJava3AdapterKt {
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R initial);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
}
diff --git a/compose/runtime/runtime-rxjava3/api/restricted_current.ignore b/compose/runtime/runtime-rxjava3/api/restricted_current.ignore
new file mode 100644
index 0000000..33b8519
--- /dev/null
+++ b/compose/runtime/runtime-rxjava3/api/restricted_current.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Flowable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Maybe<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Observable<T> arg1, R initial)
+InvalidNullConversion: androidx.compose.runtime.rxjava3.RxJava3AdapterKt#subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.rxjava3.RxJava3AdapterKt.subscribeAsState(io.reactivex.rxjava3.core.Single<T> arg1, R initial)
diff --git a/compose/runtime/runtime-rxjava3/api/restricted_current.txt b/compose/runtime/runtime-rxjava3/api/restricted_current.txt
index 1930cc8..aa5ec91 100644
--- a/compose/runtime/runtime-rxjava3/api/restricted_current.txt
+++ b/compose/runtime/runtime-rxjava3/api/restricted_current.txt
@@ -2,10 +2,10 @@
package androidx.compose.runtime.rxjava3 {
public final class RxJava3AdapterKt {
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R? initial);
- method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R? initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R initial);
+ method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R initial);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
}
diff --git a/compose/runtime/runtime-saveable/api/current.ignore b/compose/runtime/runtime-saveable/api/current.ignore
new file mode 100644
index 0000000..bc98d1f
--- /dev/null
+++ b/compose/runtime/runtime-saveable/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.saveable.Saver#save(androidx.compose.runtime.saveable.SaverScope, Original) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.saveable.Saver.save(androidx.compose.runtime.saveable.SaverScope arg1, Original value)
diff --git a/compose/runtime/runtime-saveable/api/current.txt b/compose/runtime/runtime-saveable/api/current.txt
index ce5d51b..bdc843c 100644
--- a/compose/runtime/runtime-saveable/api/current.txt
+++ b/compose/runtime/runtime-saveable/api/current.txt
@@ -42,7 +42,7 @@
public interface Saver<Original, Saveable> {
method public Original? restore(Saveable value);
- method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original? value);
+ method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
}
public final class SaverKt {
diff --git a/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt b/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
index ce5d51b..bdc843c 100644
--- a/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime-saveable/api/public_plus_experimental_current.txt
@@ -42,7 +42,7 @@
public interface Saver<Original, Saveable> {
method public Original? restore(Saveable value);
- method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original? value);
+ method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
}
public final class SaverKt {
diff --git a/compose/runtime/runtime-saveable/api/restricted_current.ignore b/compose/runtime/runtime-saveable/api/restricted_current.ignore
new file mode 100644
index 0000000..bc98d1f
--- /dev/null
+++ b/compose/runtime/runtime-saveable/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.runtime.saveable.Saver#save(androidx.compose.runtime.saveable.SaverScope, Original) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.saveable.Saver.save(androidx.compose.runtime.saveable.SaverScope arg1, Original value)
diff --git a/compose/runtime/runtime-saveable/api/restricted_current.txt b/compose/runtime/runtime-saveable/api/restricted_current.txt
index ce5d51b..bdc843c 100644
--- a/compose/runtime/runtime-saveable/api/restricted_current.txt
+++ b/compose/runtime/runtime-saveable/api/restricted_current.txt
@@ -42,7 +42,7 @@
public interface Saver<Original, Saveable> {
method public Original? restore(Saveable value);
- method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original? value);
+ method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
}
public final class SaverKt {
diff --git a/compose/runtime/runtime/api/api_lint.ignore b/compose/runtime/runtime/api/api_lint.ignore
index d1ce6c3..936df8e 100644
--- a/compose/runtime/runtime/api/api_lint.ignore
+++ b/compose/runtime/runtime/api/api_lint.ignore
@@ -9,6 +9,34 @@
Method Failure.check appears to be throwing androidx.compose.runtime.snapshots.SnapshotApplyConflictException; this should be recorded with a @Throws annotation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
+GetterSetterNames: androidx.compose.runtime.BroadcastFrameClock#getHasAwaiters():
+ Getter for boolean property `hasAwaiters` is named `getHasAwaiters` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.Composition#getHasInvalidations():
+ Getter for boolean property `hasInvalidations` is named `getHasInvalidations` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.ControlledComposition#getHasPendingChanges():
+ Getter for boolean property `hasPendingChanges` is named `getHasPendingChanges` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.Recomposer#getHasPendingWork():
+ Getter for boolean property `hasPendingWork` is named `getHasPendingWork` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.runtime.RecomposerInfo#getHasPendingWork():
+ Getter for boolean property `hasPendingWork` is named `getHasPendingWork` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field Composer.defaultsInvalid:
+ Invalid name for boolean property `defaultsInvalid`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Composer.inserting:
+ Invalid name for boolean property `inserting`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Composer.skipping:
+ Invalid name for boolean property `skipping`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field MutableSnapshot.readOnly:
+ Invalid name for boolean property `readOnly`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Snapshot.readOnly:
+ Invalid name for boolean property `readOnly`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SnapshotApplyResult.Failure.succeeded:
+ Invalid name for boolean property `succeeded`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SnapshotApplyResult.Success.succeeded:
+ Invalid name for boolean property `succeeded`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SnapshotApplyResult.succeeded:
+ Invalid name for boolean property `succeeded`. Should start with one of `has`, `can`, `should`, `is`.
+
+
KotlinOperator: androidx.compose.runtime.Updater#set(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>):
Note that adding the `operator` keyword would allow calling this method using operator syntax
KotlinOperator: androidx.compose.runtime.Updater#set(int, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit>):
@@ -17,18 +45,14 @@
Note that adding the `operator` keyword would allow calling this method using operator syntax
-MissingNullability: androidx.compose.runtime.collection.MutableVector#mapIndexedNotNull(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R>):
- Missing nullability on method `mapIndexedNotNull` return
-MissingNullability: androidx.compose.runtime.collection.MutableVector#mapNotNull(kotlin.jvm.functions.Function1<? super T,? extends R>):
- Missing nullability on method `mapNotNull` return
MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#MutableVector(int):
Missing nullability on method `MutableVector` return
-MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#MutableVector(int, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends T>):
- Missing nullability on method `MutableVector` return
MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#mutableVectorOf():
Missing nullability on method `mutableVectorOf` return
-MissingNullability: androidx.compose.runtime.collection.MutableVectorKt#mutableVectorOf(T):
- Missing nullability on method `mutableVectorOf` return
+MissingNullability: androidx.compose.runtime.snapshots.SnapshotStateMap#get(Object) parameter #0:
+ Missing nullability on parameter `key` in method `get`
+MissingNullability: androidx.compose.runtime.snapshots.SnapshotStateMap#remove(Object) parameter #0:
+ Missing nullability on parameter `key` in method `remove`
NoByteOrShort: androidx.compose.runtime.Composer#changed(byte) parameter #0:
diff --git a/compose/runtime/runtime/api/current.ignore b/compose/runtime/runtime/api/current.ignore
index 1589837..1e4b20b 100644
--- a/compose/runtime/runtime/api/current.ignore
+++ b/compose/runtime/runtime/api/current.ignore
@@ -1,8 +1,108 @@
// Baseline format: 1.0
AddedAbstractMethod: androidx.compose.runtime.Composer#getCurrentCompositionLocalMap():
Added method androidx.compose.runtime.Composer.getCurrentCompositionLocalMap()
-AddedAbstractMethod: androidx.compose.runtime.CompositionContext#getEffectCoroutineContext():
- Added method androidx.compose.runtime.CompositionContext.getEffectCoroutineContext()
+
+
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#AbstractApplier(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter root in androidx.compose.runtime.AbstractApplier(T root)
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#down(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.AbstractApplier.down(T node)
+InvalidNullConversion: androidx.compose.runtime.Applier#down(N) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.Applier.down(N node)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertBottomUp(int, N) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertBottomUp(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertTopDown(int, N) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertTopDown(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Composer#apply(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Composer.apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#provides(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.provides(T value)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#providesDefault(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.providesDefault(T value)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter a in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter b in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter previous in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter current in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter applied in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R, kotlin.coroutines.CoroutineContext) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.SnapshotStateKt.collectAsState(kotlinx.coroutines.flow.Flow<? extends T> arg1, R initial, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#mutableStateOf(T, androidx.compose.runtime.SnapshotMutationPolicy<T>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.mutableStateOf(T value, androidx.compose.runtime.SnapshotMutationPolicy<T> policy)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, Object key2, Object key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, Object key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object[], kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object[] keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#rememberUpdatedState(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter newValue in androidx.compose.runtime.SnapshotStateKt.rememberUpdatedState(T newValue)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#setValue(androidx.compose.runtime.MutableState<T>, Object, kotlin.reflect.KProperty<?>, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.setValue(androidx.compose.runtime.MutableState<T> arg1, Object thisObj, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.runtime.Updater#set(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.Updater#update(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#contains(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#fold(R, kotlin.jvm.functions.Function2<? super R,? super T,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRight(R, kotlin.jvm.functions.Function2<? super T,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRightIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#indexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#lastIndexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#minusAssign(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.minusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#plusAssign(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.plusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#remove(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#set(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#contains(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#indexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#lastIndexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#remove(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#set(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsKey(K) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.containsKey(K key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsValue(V) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.containsValue(V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#get(Object) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.get(Object key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#remove(Object) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.remove(Object key)
RemovedClass: androidx.compose.runtime.SnapshotStateKt:
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index 852d95f..59a556b 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -2,18 +2,18 @@
package androidx.compose.runtime {
public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
- ctor public AbstractApplier(T? root);
+ ctor public AbstractApplier(T root);
method public final void clear();
- method public void down(T? node);
- method public T! getCurrent();
- method public final T! getRoot();
+ method public void down(T node);
+ method public T getCurrent();
+ method public final T getRoot();
method protected final void move(java.util.List<T>, int from, int to, int count);
method protected abstract void onClear();
method protected final void remove(java.util.List<T>, int index, int count);
method protected void setCurrent(T!);
method public void up();
- property public T! current;
- property public final T! root;
+ property public T current;
+ property public final T root;
}
public final class ActualAndroid_androidKt {
@@ -23,16 +23,16 @@
@kotlin.jvm.JvmDefaultWithCompatibility public interface Applier<N> {
method public void clear();
- method public void down(N? node);
- method public N! getCurrent();
- method public void insertBottomUp(int index, N? instance);
- method public void insertTopDown(int index, N? instance);
+ method public void down(N node);
+ method public N getCurrent();
+ method public void insertBottomUp(int index, N instance);
+ method public void insertTopDown(int index, N instance);
method public void move(int from, int to, int count);
method public default void onBeginChanges();
method public default void onEndChanges();
method public void remove(int index, int count);
method public void up();
- property public abstract N! current;
+ property public abstract N current;
}
public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
@@ -75,12 +75,12 @@
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static int getCurrentCompositeKeyHash();
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionLocalContext getCurrentCompositionLocalContext();
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.runtime.RecomposeScope getCurrentRecomposeScope();
- method @androidx.compose.runtime.Composable public static inline <T> T! key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionContext rememberCompositionContext();
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static final androidx.compose.runtime.Composer currentComposer;
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static final int currentCompositeKeyHash;
@@ -98,7 +98,7 @@
}
public sealed interface Composer {
- method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
method @androidx.compose.runtime.ComposeCompilerApi public boolean changed(Object? value);
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
@@ -170,7 +170,7 @@
}
public final class ComposerKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
method @androidx.compose.runtime.ComposeCompilerApi public static boolean isTraceInProgress();
method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
@@ -215,7 +215,7 @@
}
public sealed interface CompositionLocalMap {
- method public operator <T> T! get(androidx.compose.runtime.CompositionLocal<T> key);
+ method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
}
@@ -229,7 +229,7 @@
method public void applyLateChanges();
method public void changesApplied();
method public void composeContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method public <R> R! delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
+ method public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
method public boolean getHasPendingChanges();
method public void invalidateAll();
method public boolean isComposing();
@@ -259,7 +259,7 @@
method public double getDoubleValue();
method public default Double getValue();
property public abstract double doubleValue;
- property public default Double value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
}
public final class EffectsKt {
@@ -284,7 +284,7 @@
method public float getFloatValue();
method public default Float getValue();
property public abstract float floatValue;
- property public default Float value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
}
@androidx.compose.runtime.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Immutable {
@@ -294,14 +294,14 @@
method public int getIntValue();
method public default Integer getValue();
property public abstract int intValue;
- property public default Integer value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LongState extends androidx.compose.runtime.State<java.lang.Long> {
method public long getLongValue();
method public default Long getValue();
property public abstract long longValue;
- property public default Long value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
@@ -337,35 +337,35 @@
method public void setDoubleValue(double);
method public default void setValue(double);
property public abstract double doubleValue;
- property public default Double value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableFloatState extends androidx.compose.runtime.FloatState androidx.compose.runtime.MutableState<java.lang.Float> {
method public void setFloatValue(float);
method public default void setValue(float);
property public abstract float floatValue;
- property public default Float value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableIntState extends androidx.compose.runtime.IntState androidx.compose.runtime.MutableState<java.lang.Integer> {
method public void setIntValue(int);
method public default void setValue(int);
property public abstract int intValue;
- property public default Integer value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableLongState extends androidx.compose.runtime.LongState androidx.compose.runtime.MutableState<java.lang.Long> {
method public void setLongValue(long);
method public default void setValue(long);
property public abstract long longValue;
- property public default Long value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
}
@androidx.compose.runtime.Stable public interface MutableState<T> extends androidx.compose.runtime.State<T> {
- method public operator T! component1();
+ method public operator T component1();
method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
method public void setValue(T!);
- property public abstract T! value;
+ property public abstract T value;
}
@kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FILE}) public @interface NoLiveLiterals {
@@ -394,17 +394,17 @@
}
@androidx.compose.runtime.Stable public abstract class ProvidableCompositionLocal<T> extends androidx.compose.runtime.CompositionLocal<T> {
- method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T? value);
- method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T? value);
+ method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T value);
+ method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T value);
}
public final class ProvidedValue<T> {
method public boolean getCanOverride();
method public androidx.compose.runtime.CompositionLocal<T> getCompositionLocal();
- method public T! getValue();
+ method public T getValue();
property public final boolean canOverride;
property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
- property public final T! value;
+ property public final T value;
}
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ReadOnlyComposable {
@@ -500,8 +500,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface SnapshotMutationPolicy<T> {
- method public boolean equivalent(T? a, T? b);
- method public default T? merge(T? previous, T? current, T? applied);
+ method public boolean equivalent(T a, T b);
+ method public default T? merge(T previous, T current, T applied);
}
public final class SnapshotStateExtensionsKt {
@@ -513,24 +513,24 @@
public final class SnapshotStateKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R? initial, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
- method public static inline operator <T> T! getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
+ method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
- method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T? value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+ method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> referentialEqualityPolicy();
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T? newValue);
- method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T? value);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T newValue);
+ method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T value);
method public static <T> kotlinx.coroutines.flow.Flow<T> snapshotFlow(kotlin.jvm.functions.Function0<? extends T> block);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> structuralEqualityPolicy();
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> toMutableStateList(java.util.Collection<? extends T>);
@@ -544,8 +544,8 @@
}
@androidx.compose.runtime.Stable public interface State<T> {
- method public T! getValue();
- property public abstract T! value;
+ method public T getValue();
+ property public abstract T value;
}
@kotlin.jvm.JvmInline public final value class Updater<T> {
@@ -553,9 +553,9 @@
method public void init(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public void reconcile(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void set(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
- method public <V> void set(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method public <V> void set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
method public inline void update(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
- method public <V> void update(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
}
}
@@ -563,8 +563,8 @@
package androidx.compose.runtime.collection {
public final class MutableVector<T> implements java.util.RandomAccess {
- method public boolean add(T? element);
- method public void add(int index, T? element);
+ method public boolean add(T element);
+ method public void add(int index, T element);
method public boolean addAll(int index, java.util.List<? extends T> elements);
method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
method public inline boolean addAll(java.util.List<? extends T> elements);
@@ -575,53 +575,53 @@
method public inline boolean any(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public java.util.List<T> asMutableList();
method public void clear();
- method public operator boolean contains(T? element);
+ method public operator boolean contains(T element);
method public boolean containsAll(java.util.List<? extends T> elements);
method public boolean containsAll(java.util.Collection<? extends T> elements);
method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<T> elements);
method public boolean contentEquals(androidx.compose.runtime.collection.MutableVector<T> other);
method public void ensureCapacity(int capacity);
- method public T! first();
- method public inline T! first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+ method public T first();
+ method public inline T first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline T? firstOrNull();
method public inline T? firstOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public inline <R> R! fold(R? initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
- method public inline <R> R! foldIndexed(R? initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
- method public inline <R> R! foldRight(R? initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
- method public inline <R> R! foldRightIndexed(R? initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
+ method public inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
+ method public inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
+ method public inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
+ method public inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
method public inline void forEach(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
method public inline void forEachReversed(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
- method public inline operator T! get(int index);
+ method public inline operator T get(int index);
method public inline kotlin.ranges.IntRange getIndices();
method public inline int getLastIndex();
method public int getSize();
- method public int indexOf(T? element);
+ method public int indexOf(T element);
method public inline int indexOfFirst(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline int indexOfLast(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public boolean isEmpty();
method public boolean isNotEmpty();
- method public T! last();
- method public inline T! last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public int lastIndexOf(T? element);
+ method public T last();
+ method public inline T last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+ method public int lastIndexOf(T element);
method public inline T? lastOrNull();
method public inline T? lastOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline <reified R> R![] map(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public inline <reified R> R![] mapIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapIndexedNotNull(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapNotNull(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
- method public inline operator void minusAssign(T? element);
- method public inline operator void plusAssign(T? element);
- method public boolean remove(T? element);
+ method public inline operator void minusAssign(T element);
+ method public inline operator void plusAssign(T element);
+ method public boolean remove(T element);
method public boolean removeAll(java.util.List<? extends T> elements);
method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
method public boolean removeAll(java.util.Collection<? extends T> elements);
- method public T! removeAt(int index);
+ method public T removeAt(int index);
method public void removeRange(int start, int end);
method public boolean retainAll(java.util.Collection<? extends T> elements);
method public inline boolean reversedAny(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public operator T! set(int index, T? element);
+ method public operator T set(int index, T element);
method public void sortWith(java.util.Comparator<T> comparator);
method public inline int sumBy(kotlin.jvm.functions.Function1<? super T,java.lang.Integer> selector);
property public final inline kotlin.ranges.IntRange indices;
@@ -724,6 +724,11 @@
package androidx.compose.runtime.snapshots {
+ @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.PROPERTY) public @interface AutoboxingStateValueProperty {
+ method public abstract String preferredPropertyName();
+ property public abstract String preferredPropertyName;
+ }
+
public class MutableSnapshot extends androidx.compose.runtime.snapshots.Snapshot {
method public androidx.compose.runtime.snapshots.SnapshotApplyResult apply();
method public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? getReadObserver();
@@ -745,7 +750,7 @@
public abstract sealed class Snapshot {
method public void dispose();
- method public final inline <T> T! enter(kotlin.jvm.functions.Function0<? extends T> block);
+ method public final inline <T> T enter(kotlin.jvm.functions.Function0<? extends T> block);
method public int getId();
method public abstract boolean getReadOnly();
method public abstract androidx.compose.runtime.snapshots.Snapshot getRoot();
@@ -759,16 +764,16 @@
public static final class Snapshot.Companion {
method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
- method public inline <T> T! global(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
method public void notifyObjectsInitialized();
- method public <T> T! observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
+ method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
method public androidx.compose.runtime.snapshots.ObserverHandle registerGlobalWriteObserver(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> observer);
method public void sendApplyNotifications();
method public androidx.compose.runtime.snapshots.MutableSnapshot takeMutableSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver);
method public androidx.compose.runtime.snapshots.Snapshot takeSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
- method public inline <R> R! withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
- method public inline <T> T! withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
+ method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
property public final androidx.compose.runtime.snapshots.Snapshot current;
}
@@ -803,9 +808,9 @@
public final class SnapshotKt {
method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state);
method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
}
public interface SnapshotMutableState<T> extends androidx.compose.runtime.MutableState<T> {
@@ -815,29 +820,29 @@
@androidx.compose.runtime.Stable public final class SnapshotStateList<T> implements kotlin.jvm.internal.markers.KMutableList java.util.List<T> androidx.compose.runtime.snapshots.StateObject {
ctor public SnapshotStateList();
- method public boolean add(T? element);
- method public void add(int index, T? element);
+ method public boolean add(T element);
+ method public void add(int index, T element);
method public boolean addAll(int index, java.util.Collection<? extends T> elements);
method public boolean addAll(java.util.Collection<? extends T> elements);
method public void clear();
- method public boolean contains(T? element);
+ method public boolean contains(T element);
method public boolean containsAll(java.util.Collection<E!> elements);
- method public T! get(int index);
+ method public T get(int index);
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public int getSize();
- method public int indexOf(T? element);
+ method public int indexOf(T element);
method public boolean isEmpty();
method public java.util.Iterator<T> iterator();
- method public int lastIndexOf(T? element);
+ method public int lastIndexOf(T element);
method public java.util.ListIterator<T> listIterator();
method public java.util.ListIterator<T> listIterator(int index);
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
- method public boolean remove(T? element);
+ method public boolean remove(T element);
method public boolean removeAll(java.util.Collection<E!> elements);
- method public T! removeAt(int index);
+ method public T removeAt(int index);
method public void removeRange(int fromIndex, int toIndex);
method public boolean retainAll(java.util.Collection<E!> elements);
- method public T! set(int index, T? element);
+ method public T set(int index, T element);
method public java.util.List<T> subList(int fromIndex, int toIndex);
method public java.util.List<T> toList();
property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
@@ -847,9 +852,9 @@
@androidx.compose.runtime.Stable public final class SnapshotStateMap<K, V> implements kotlin.jvm.internal.markers.KMutableMap java.util.Map<K,V> androidx.compose.runtime.snapshots.StateObject {
ctor public SnapshotStateMap();
method public void clear();
- method public boolean containsKey(K? key);
- method public boolean containsValue(V? value);
- method public V? get(Object? key);
+ method public boolean containsKey(K key);
+ method public boolean containsValue(V value);
+ method public V? get(Object key);
method public java.util.Set<java.util.Map.Entry<K,V>> getEntries();
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public java.util.Set<K> getKeys();
@@ -857,9 +862,9 @@
method public java.util.Collection<V> getValues();
method public boolean isEmpty();
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
- method public V? put(K? key, V? value);
+ method public V? put(K key, V value);
method public void putAll(java.util.Map<? extends K,? extends V> from);
- method public V? remove(Object? key);
+ method public V? remove(Object key);
method public java.util.Map<K,V> toMap();
property public java.util.Set<java.util.Map.Entry<K,V>> entries;
property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
diff --git a/compose/runtime/runtime/api/public_plus_experimental_current.txt b/compose/runtime/runtime/api/public_plus_experimental_current.txt
index 881f541..9ce9384 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_current.txt
@@ -2,18 +2,18 @@
package androidx.compose.runtime {
public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
- ctor public AbstractApplier(T? root);
+ ctor public AbstractApplier(T root);
method public final void clear();
- method public void down(T? node);
- method public T! getCurrent();
- method public final T! getRoot();
+ method public void down(T node);
+ method public T getCurrent();
+ method public final T getRoot();
method protected final void move(java.util.List<T>, int from, int to, int count);
method protected abstract void onClear();
method protected final void remove(java.util.List<T>, int index, int count);
method protected void setCurrent(T!);
method public void up();
- property public T! current;
- property public final T! root;
+ property public T current;
+ property public final T root;
}
public final class ActualAndroid_androidKt {
@@ -23,16 +23,16 @@
@kotlin.jvm.JvmDefaultWithCompatibility public interface Applier<N> {
method public void clear();
- method public void down(N? node);
- method public N! getCurrent();
- method public void insertBottomUp(int index, N? instance);
- method public void insertTopDown(int index, N? instance);
+ method public void down(N node);
+ method public N getCurrent();
+ method public void insertBottomUp(int index, N instance);
+ method public void insertTopDown(int index, N instance);
method public void move(int from, int to, int count);
method public default void onBeginChanges();
method public default void onEndChanges();
method public void remove(int index, int count);
method public void up();
- property public abstract N! current;
+ property public abstract N current;
}
public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
@@ -80,12 +80,12 @@
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static int getCurrentCompositeKeyHash();
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionLocalContext getCurrentCompositionLocalContext();
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.runtime.RecomposeScope getCurrentRecomposeScope();
- method @androidx.compose.runtime.Composable public static inline <T> T! key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionContext rememberCompositionContext();
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static final androidx.compose.runtime.Composer currentComposer;
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static final int currentCompositeKeyHash;
@@ -103,7 +103,7 @@
}
public sealed interface Composer {
- method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
method @androidx.compose.runtime.InternalComposeApi public androidx.compose.runtime.CompositionContext buildContext();
method @androidx.compose.runtime.ComposeCompilerApi public boolean changed(Object? value);
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
@@ -116,7 +116,7 @@
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(double value);
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changedInstance(Object? value);
method public void collectParameterInformation();
- method @androidx.compose.runtime.InternalComposeApi public <T> T! consume(androidx.compose.runtime.CompositionLocal<T> key);
+ method @androidx.compose.runtime.InternalComposeApi public <T> T consume(androidx.compose.runtime.CompositionLocal<T> key);
method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
@@ -185,7 +185,7 @@
}
public final class ComposerKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
method @androidx.compose.runtime.ComposeCompilerApi public static boolean isTraceInProgress();
method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
@@ -233,7 +233,7 @@
}
public sealed interface CompositionLocalMap {
- method public operator <T> T! get(androidx.compose.runtime.CompositionLocal<T> key);
+ method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
}
@@ -253,7 +253,7 @@
method public void applyLateChanges();
method public void changesApplied();
method public void composeContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method public <R> R! delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
+ method public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
method @androidx.compose.runtime.InternalComposeApi public void disposeUnusedMovableContent(androidx.compose.runtime.MovableContentState state);
method public boolean getHasPendingChanges();
method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
@@ -286,7 +286,7 @@
method public double getDoubleValue();
method public default Double getValue();
property public abstract double doubleValue;
- property public default Double value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
}
public final class EffectsKt {
@@ -314,7 +314,7 @@
method public float getFloatValue();
method public default Float getValue();
property public abstract float floatValue;
- property public default Float value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
}
@androidx.compose.runtime.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Immutable {
@@ -324,7 +324,7 @@
method public int getIntValue();
method public default Integer getValue();
property public abstract int intValue;
- property public default Integer value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
}
@kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API for Compose modules that may change frequently " + "and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalComposeApi {
@@ -337,7 +337,7 @@
method public long getLongValue();
method public default Long getValue();
property public abstract long longValue;
- property public default Long value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
@@ -385,35 +385,35 @@
method public void setDoubleValue(double);
method public default void setValue(double);
property public abstract double doubleValue;
- property public default Double value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableFloatState extends androidx.compose.runtime.FloatState androidx.compose.runtime.MutableState<java.lang.Float> {
method public void setFloatValue(float);
method public default void setValue(float);
property public abstract float floatValue;
- property public default Float value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableIntState extends androidx.compose.runtime.IntState androidx.compose.runtime.MutableState<java.lang.Integer> {
method public void setIntValue(int);
method public default void setValue(int);
property public abstract int intValue;
- property public default Integer value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableLongState extends androidx.compose.runtime.LongState androidx.compose.runtime.MutableState<java.lang.Long> {
method public void setLongValue(long);
method public default void setValue(long);
property public abstract long longValue;
- property public default Long value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
}
@androidx.compose.runtime.Stable public interface MutableState<T> extends androidx.compose.runtime.State<T> {
- method public operator T! component1();
+ method public operator T component1();
method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
method public void setValue(T!);
- property public abstract T! value;
+ property public abstract T value;
}
@kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FILE}) public @interface NoLiveLiterals {
@@ -442,17 +442,17 @@
}
@androidx.compose.runtime.Stable public abstract class ProvidableCompositionLocal<T> extends androidx.compose.runtime.CompositionLocal<T> {
- method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T? value);
- method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T? value);
+ method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T value);
+ method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T value);
}
public final class ProvidedValue<T> {
method public boolean getCanOverride();
method public androidx.compose.runtime.CompositionLocal<T> getCompositionLocal();
- method public T! getValue();
+ method public T getValue();
property public final boolean canOverride;
property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
- property public final T! value;
+ property public final T value;
}
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ReadOnlyComposable {
@@ -549,8 +549,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface SnapshotMutationPolicy<T> {
- method public boolean equivalent(T? a, T? b);
- method public default T? merge(T? previous, T? current, T? applied);
+ method public boolean equivalent(T a, T b);
+ method public default T? merge(T previous, T current, T applied);
}
public final class SnapshotStateExtensionsKt {
@@ -562,24 +562,24 @@
public final class SnapshotStateKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R? initial, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
- method public static inline operator <T> T! getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
+ method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
- method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T? value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+ method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> referentialEqualityPolicy();
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T? newValue);
- method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T? value);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T newValue);
+ method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T value);
method public static <T> kotlinx.coroutines.flow.Flow<T> snapshotFlow(kotlin.jvm.functions.Function0<? extends T> block);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> structuralEqualityPolicy();
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> toMutableStateList(java.util.Collection<? extends T>);
@@ -593,8 +593,8 @@
}
@androidx.compose.runtime.Stable public interface State<T> {
- method public T! getValue();
- property public abstract T! value;
+ method public T getValue();
+ property public abstract T value;
}
@kotlin.jvm.JvmInline public final value class Updater<T> {
@@ -602,9 +602,9 @@
method public void init(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public void reconcile(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void set(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
- method public <V> void set(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method public <V> void set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
method public inline void update(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
- method public <V> void update(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
}
}
@@ -612,8 +612,8 @@
package androidx.compose.runtime.collection {
public final class MutableVector<T> implements java.util.RandomAccess {
- method public boolean add(T? element);
- method public void add(int index, T? element);
+ method public boolean add(T element);
+ method public void add(int index, T element);
method public boolean addAll(int index, java.util.List<? extends T> elements);
method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
method public inline boolean addAll(java.util.List<? extends T> elements);
@@ -624,53 +624,53 @@
method public inline boolean any(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public java.util.List<T> asMutableList();
method public void clear();
- method public operator boolean contains(T? element);
+ method public operator boolean contains(T element);
method public boolean containsAll(java.util.List<? extends T> elements);
method public boolean containsAll(java.util.Collection<? extends T> elements);
method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<T> elements);
method public boolean contentEquals(androidx.compose.runtime.collection.MutableVector<T> other);
method public void ensureCapacity(int capacity);
- method public T! first();
- method public inline T! first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+ method public T first();
+ method public inline T first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline T? firstOrNull();
method public inline T? firstOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public inline <R> R! fold(R? initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
- method public inline <R> R! foldIndexed(R? initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
- method public inline <R> R! foldRight(R? initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
- method public inline <R> R! foldRightIndexed(R? initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
+ method public inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
+ method public inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
+ method public inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
+ method public inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
method public inline void forEach(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
method public inline void forEachReversed(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
- method public inline operator T! get(int index);
+ method public inline operator T get(int index);
method public inline kotlin.ranges.IntRange getIndices();
method public inline int getLastIndex();
method public int getSize();
- method public int indexOf(T? element);
+ method public int indexOf(T element);
method public inline int indexOfFirst(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline int indexOfLast(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public boolean isEmpty();
method public boolean isNotEmpty();
- method public T! last();
- method public inline T! last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public int lastIndexOf(T? element);
+ method public T last();
+ method public inline T last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+ method public int lastIndexOf(T element);
method public inline T? lastOrNull();
method public inline T? lastOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline <reified R> R![] map(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public inline <reified R> R![] mapIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapIndexedNotNull(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapNotNull(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
- method public inline operator void minusAssign(T? element);
- method public inline operator void plusAssign(T? element);
- method public boolean remove(T? element);
+ method public inline operator void minusAssign(T element);
+ method public inline operator void plusAssign(T element);
+ method public boolean remove(T element);
method public boolean removeAll(java.util.List<? extends T> elements);
method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
method public boolean removeAll(java.util.Collection<? extends T> elements);
- method public T! removeAt(int index);
+ method public T removeAt(int index);
method public void removeRange(int start, int end);
method public boolean retainAll(java.util.Collection<? extends T> elements);
method public inline boolean reversedAny(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public operator T! set(int index, T? element);
+ method public operator T set(int index, T element);
method public void sortWith(java.util.Comparator<T> comparator);
method public inline int sumBy(kotlin.jvm.functions.Function1<? super T,java.lang.Integer> selector);
property public final inline kotlin.ranges.IntRange indices;
@@ -756,7 +756,7 @@
public final class LiveLiteralKt {
method @androidx.compose.runtime.InternalComposeApi public static void enableLiveLiterals();
method public static boolean isLiveLiteralsEnabled();
- method @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.InternalComposeApi public static <T> androidx.compose.runtime.State<T> liveLiteral(String key, T? value);
+ method @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.InternalComposeApi public static <T> androidx.compose.runtime.State<T> liveLiteral(String key, T value);
method @androidx.compose.runtime.InternalComposeApi public static void updateLiveLiteralValue(String key, Object? value);
property public static final boolean isLiveLiteralsEnabled;
}
@@ -790,6 +790,11 @@
package androidx.compose.runtime.snapshots {
+ @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.PROPERTY) public @interface AutoboxingStateValueProperty {
+ method public abstract String preferredPropertyName();
+ property public abstract String preferredPropertyName;
+ }
+
public class MutableSnapshot extends androidx.compose.runtime.snapshots.Snapshot {
method public androidx.compose.runtime.snapshots.SnapshotApplyResult apply();
method public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? getReadObserver();
@@ -811,7 +816,7 @@
public abstract sealed class Snapshot {
method public void dispose();
- method public final inline <T> T! enter(kotlin.jvm.functions.Function0<? extends T> block);
+ method public final inline <T> T enter(kotlin.jvm.functions.Function0<? extends T> block);
method public int getId();
method public abstract boolean getReadOnly();
method public abstract androidx.compose.runtime.snapshots.Snapshot getRoot();
@@ -827,17 +832,17 @@
public static final class Snapshot.Companion {
method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
- method public inline <T> T! global(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
method public void notifyObjectsInitialized();
- method public <T> T! observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
+ method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
method @androidx.compose.runtime.InternalComposeApi public int openSnapshotCount();
method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
method public androidx.compose.runtime.snapshots.ObserverHandle registerGlobalWriteObserver(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> observer);
method public void sendApplyNotifications();
method public androidx.compose.runtime.snapshots.MutableSnapshot takeMutableSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver);
method public androidx.compose.runtime.snapshots.Snapshot takeSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
- method public inline <R> R! withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
- method public inline <T> T! withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
+ method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
property public final androidx.compose.runtime.snapshots.Snapshot current;
}
@@ -883,9 +888,9 @@
public final class SnapshotKt {
method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state);
method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
}
public interface SnapshotMutableState<T> extends androidx.compose.runtime.MutableState<T> {
@@ -895,29 +900,29 @@
@androidx.compose.runtime.Stable public final class SnapshotStateList<T> implements kotlin.jvm.internal.markers.KMutableList java.util.List<T> androidx.compose.runtime.snapshots.StateObject {
ctor public SnapshotStateList();
- method public boolean add(T? element);
- method public void add(int index, T? element);
+ method public boolean add(T element);
+ method public void add(int index, T element);
method public boolean addAll(int index, java.util.Collection<? extends T> elements);
method public boolean addAll(java.util.Collection<? extends T> elements);
method public void clear();
- method public boolean contains(T? element);
+ method public boolean contains(T element);
method public boolean containsAll(java.util.Collection<E!> elements);
- method public T! get(int index);
+ method public T get(int index);
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public int getSize();
- method public int indexOf(T? element);
+ method public int indexOf(T element);
method public boolean isEmpty();
method public java.util.Iterator<T> iterator();
- method public int lastIndexOf(T? element);
+ method public int lastIndexOf(T element);
method public java.util.ListIterator<T> listIterator();
method public java.util.ListIterator<T> listIterator(int index);
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
- method public boolean remove(T? element);
+ method public boolean remove(T element);
method public boolean removeAll(java.util.Collection<E!> elements);
- method public T! removeAt(int index);
+ method public T removeAt(int index);
method public void removeRange(int fromIndex, int toIndex);
method public boolean retainAll(java.util.Collection<E!> elements);
- method public T! set(int index, T? element);
+ method public T set(int index, T element);
method public java.util.List<T> subList(int fromIndex, int toIndex);
method public java.util.List<T> toList();
property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
@@ -927,9 +932,9 @@
@androidx.compose.runtime.Stable public final class SnapshotStateMap<K, V> implements kotlin.jvm.internal.markers.KMutableMap java.util.Map<K,V> androidx.compose.runtime.snapshots.StateObject {
ctor public SnapshotStateMap();
method public void clear();
- method public boolean containsKey(K? key);
- method public boolean containsValue(V? value);
- method public V? get(Object? key);
+ method public boolean containsKey(K key);
+ method public boolean containsValue(V value);
+ method public V? get(Object key);
method public java.util.Set<java.util.Map.Entry<K,V>> getEntries();
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public java.util.Set<K> getKeys();
@@ -937,9 +942,9 @@
method public java.util.Collection<V> getValues();
method public boolean isEmpty();
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
- method public V? put(K? key, V? value);
+ method public V? put(K key, V value);
method public void putAll(java.util.Map<? extends K,? extends V> from);
- method public V? remove(Object? key);
+ method public V? remove(Object key);
method public java.util.Map<K,V> toMap();
property public java.util.Set<java.util.Map.Entry<K,V>> entries;
property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
diff --git a/compose/runtime/runtime/api/restricted_current.ignore b/compose/runtime/runtime/api/restricted_current.ignore
index 1589837..1e4b20b 100644
--- a/compose/runtime/runtime/api/restricted_current.ignore
+++ b/compose/runtime/runtime/api/restricted_current.ignore
@@ -1,8 +1,108 @@
// Baseline format: 1.0
AddedAbstractMethod: androidx.compose.runtime.Composer#getCurrentCompositionLocalMap():
Added method androidx.compose.runtime.Composer.getCurrentCompositionLocalMap()
-AddedAbstractMethod: androidx.compose.runtime.CompositionContext#getEffectCoroutineContext():
- Added method androidx.compose.runtime.CompositionContext.getEffectCoroutineContext()
+
+
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#AbstractApplier(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter root in androidx.compose.runtime.AbstractApplier(T root)
+InvalidNullConversion: androidx.compose.runtime.AbstractApplier#down(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.AbstractApplier.down(T node)
+InvalidNullConversion: androidx.compose.runtime.Applier#down(N) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter node in androidx.compose.runtime.Applier.down(N node)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertBottomUp(int, N) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertBottomUp(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Applier#insertTopDown(int, N) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter instance in androidx.compose.runtime.Applier.insertTopDown(int index, N instance)
+InvalidNullConversion: androidx.compose.runtime.Composer#apply(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Composer.apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#provides(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.provides(T value)
+InvalidNullConversion: androidx.compose.runtime.ProvidableCompositionLocal#providesDefault(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.ProvidableCompositionLocal.providesDefault(T value)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter a in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#equivalent(T, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter b in androidx.compose.runtime.SnapshotMutationPolicy.equivalent(T a, T b)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter previous in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter current in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotMutationPolicy#merge(T, T, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter applied in androidx.compose.runtime.SnapshotMutationPolicy.merge(T previous, T current, T applied)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R, kotlin.coroutines.CoroutineContext) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.SnapshotStateKt.collectAsState(kotlinx.coroutines.flow.Flow<? extends T> arg1, R initial, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#mutableStateOf(T, androidx.compose.runtime.SnapshotMutationPolicy<T>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.mutableStateOf(T value, androidx.compose.runtime.SnapshotMutationPolicy<T> policy)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, Object key2, Object key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, Object key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, Object[], kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, Object[] keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#produceState(T, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.compose.runtime.SnapshotStateKt.produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#rememberUpdatedState(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter newValue in androidx.compose.runtime.SnapshotStateKt.rememberUpdatedState(T newValue)
+InvalidNullConversion: androidx.compose.runtime.SnapshotStateKt#setValue(androidx.compose.runtime.MutableState<T>, Object, kotlin.reflect.KProperty<?>, T) parameter #3:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.SnapshotStateKt.setValue(androidx.compose.runtime.MutableState<T> arg1, Object thisObj, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.runtime.Updater#set(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.Updater#update(V, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.Updater.update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#add(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#contains(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#fold(R, kotlin.jvm.functions.Function2<? super R,? super T,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRight(R, kotlin.jvm.functions.Function2<? super T,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#foldRightIndexed(R, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.runtime.collection.MutableVector.foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#indexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#lastIndexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#minusAssign(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.minusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#plusAssign(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.plusAssign(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#remove(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.collection.MutableVector#set(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.collection.MutableVector.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#add(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.add(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#contains(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.contains(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#indexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.indexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#lastIndexOf(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.lastIndexOf(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#remove(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.remove(T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateList#set(int, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter element in androidx.compose.runtime.snapshots.SnapshotStateList.set(int index, T element)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsKey(K) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.containsKey(K key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#containsValue(V) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.containsValue(V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#get(Object) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.get(Object key)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#put(K, V) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.runtime.snapshots.SnapshotStateMap.put(K key, V value)
+InvalidNullConversion: androidx.compose.runtime.snapshots.SnapshotStateMap#remove(Object) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter key in androidx.compose.runtime.snapshots.SnapshotStateMap.remove(Object key)
RemovedClass: androidx.compose.runtime.SnapshotStateKt:
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index a65d447..366b6db 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -2,18 +2,18 @@
package androidx.compose.runtime {
public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
- ctor public AbstractApplier(T? root);
+ ctor public AbstractApplier(T root);
method public final void clear();
- method public void down(T? node);
- method public T! getCurrent();
- method public final T! getRoot();
+ method public void down(T node);
+ method public T getCurrent();
+ method public final T getRoot();
method protected final void move(java.util.List<T>, int from, int to, int count);
method protected abstract void onClear();
method protected final void remove(java.util.List<T>, int index, int count);
method protected void setCurrent(T!);
method public void up();
- property public T! current;
- property public final T! root;
+ property public T current;
+ property public final T root;
}
public final class ActualAndroid_androidKt {
@@ -22,21 +22,21 @@
}
public final class ActualJvm_jvmKt {
- method @kotlin.PublishedApi internal static inline <R> R! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
+ method @kotlin.PublishedApi internal static inline <R> R synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface Applier<N> {
method public void clear();
- method public void down(N? node);
- method public N! getCurrent();
- method public void insertBottomUp(int index, N? instance);
- method public void insertTopDown(int index, N? instance);
+ method public void down(N node);
+ method public N getCurrent();
+ method public void insertBottomUp(int index, N instance);
+ method public void insertTopDown(int index, N instance);
method public void move(int from, int to, int count);
method public default void onBeginChanges();
method public default void onEndChanges();
method public void remove(int index, int count);
method public void up();
- property public abstract N! current;
+ property public abstract N current;
}
public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
@@ -80,12 +80,12 @@
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionLocalContext getCurrentCompositionLocalContext();
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.runtime.RecomposeScope getCurrentRecomposeScope();
method @kotlin.PublishedApi internal static void invalidApplier();
- method @androidx.compose.runtime.Composable public static inline <T> T! key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
- method @androidx.compose.runtime.Composable public static inline <T> T! remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.Composable public static inline <T> T remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionContext rememberCompositionContext();
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static final androidx.compose.runtime.Composer currentComposer;
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static final int currentCompositeKeyHash;
@@ -103,7 +103,7 @@
}
public sealed interface Composer {
- method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
method @androidx.compose.runtime.ComposeCompilerApi public boolean changed(Object? value);
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
@@ -175,7 +175,7 @@
}
public final class ComposerKt {
- method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T! cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+ method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
method @androidx.compose.runtime.ComposeCompilerApi public static boolean isTraceInProgress();
method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
@@ -233,7 +233,7 @@
}
public sealed interface CompositionLocalMap {
- method public operator <T> T! get(androidx.compose.runtime.CompositionLocal<T> key);
+ method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
}
@@ -256,7 +256,7 @@
method public void applyLateChanges();
method public void changesApplied();
method public void composeContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method public <R> R! delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
+ method public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
method public boolean getHasPendingChanges();
method public void invalidateAll();
method public boolean isComposing();
@@ -286,7 +286,7 @@
method public double getDoubleValue();
method public default Double getValue();
property public abstract double doubleValue;
- property public default Double value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
}
public final class EffectsKt {
@@ -306,7 +306,7 @@
}
public final class ExpectKt {
- method @kotlin.PublishedApi internal static inline <R> R? synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
+ method @kotlin.PublishedApi internal static inline <R> R synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
}
@kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExplicitGroupsComposable {
@@ -316,7 +316,7 @@
method public float getFloatValue();
method public default Float getValue();
property public abstract float floatValue;
- property public default Float value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
}
@androidx.compose.runtime.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Immutable {
@@ -326,14 +326,14 @@
method public int getIntValue();
method public default Integer getValue();
property public abstract int intValue;
- property public default Integer value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LongState extends androidx.compose.runtime.State<java.lang.Long> {
method public long getLongValue();
method public default Long getValue();
property public abstract long longValue;
- property public default Long value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
@@ -369,35 +369,35 @@
method public void setDoubleValue(double);
method public default void setValue(double);
property public abstract double doubleValue;
- property public default Double value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableFloatState extends androidx.compose.runtime.FloatState androidx.compose.runtime.MutableState<java.lang.Float> {
method public void setFloatValue(float);
method public default void setValue(float);
property public abstract float floatValue;
- property public default Float value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableIntState extends androidx.compose.runtime.IntState androidx.compose.runtime.MutableState<java.lang.Integer> {
method public void setIntValue(int);
method public default void setValue(int);
property public abstract int intValue;
- property public default Integer value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
}
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableLongState extends androidx.compose.runtime.LongState androidx.compose.runtime.MutableState<java.lang.Long> {
method public void setLongValue(long);
method public default void setValue(long);
property public abstract long longValue;
- property public default Long value;
+ property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
}
@androidx.compose.runtime.Stable public interface MutableState<T> extends androidx.compose.runtime.State<T> {
- method public operator T! component1();
+ method public operator T component1();
method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
method public void setValue(T!);
- property public abstract T! value;
+ property public abstract T value;
}
@kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FILE}) public @interface NoLiveLiterals {
@@ -426,17 +426,17 @@
}
@androidx.compose.runtime.Stable public abstract class ProvidableCompositionLocal<T> extends androidx.compose.runtime.CompositionLocal<T> {
- method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T? value);
- method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T? value);
+ method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T value);
+ method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T value);
}
public final class ProvidedValue<T> {
method public boolean getCanOverride();
method public androidx.compose.runtime.CompositionLocal<T> getCompositionLocal();
- method public T! getValue();
+ method public T getValue();
property public final boolean canOverride;
property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
- property public final T! value;
+ property public final T value;
}
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ReadOnlyComposable {
@@ -536,8 +536,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface SnapshotMutationPolicy<T> {
- method public boolean equivalent(T? a, T? b);
- method public default T? merge(T? previous, T? current, T? applied);
+ method public boolean equivalent(T a, T b);
+ method public default T? merge(T previous, T current, T applied);
}
public final class SnapshotStateExtensionsKt {
@@ -549,24 +549,24 @@
public final class SnapshotStateKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R? initial, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
- method public static inline operator <T> T! getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
+ method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
- method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T? value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+ method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T? initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> referentialEqualityPolicy();
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T? newValue);
- method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T? value);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T newValue);
+ method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T value);
method public static <T> kotlinx.coroutines.flow.Flow<T> snapshotFlow(kotlin.jvm.functions.Function0<? extends T> block);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> structuralEqualityPolicy();
method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> toMutableStateList(java.util.Collection<? extends T>);
@@ -580,8 +580,8 @@
}
@androidx.compose.runtime.Stable public interface State<T> {
- method public T! getValue();
- property public abstract T! value;
+ method public T getValue();
+ property public abstract T value;
}
@kotlin.jvm.JvmInline public final value class Updater<T> {
@@ -589,9 +589,9 @@
method public void init(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public void reconcile(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void set(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
- method public <V> void set(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method public <V> void set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
method public inline void update(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
- method public <V> void update(V? value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+ method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
}
}
@@ -600,8 +600,8 @@
public final class MutableVector<T> implements java.util.RandomAccess {
ctor @kotlin.PublishedApi internal MutableVector(@kotlin.PublishedApi T![] content, int size);
- method public boolean add(T? element);
- method public void add(int index, T? element);
+ method public boolean add(T element);
+ method public void add(int index, T element);
method public boolean addAll(int index, java.util.List<? extends T> elements);
method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
method public inline boolean addAll(java.util.List<? extends T> elements);
@@ -612,53 +612,53 @@
method public inline boolean any(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public java.util.List<T> asMutableList();
method public void clear();
- method public operator boolean contains(T? element);
+ method public operator boolean contains(T element);
method public boolean containsAll(java.util.List<? extends T> elements);
method public boolean containsAll(java.util.Collection<? extends T> elements);
method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<T> elements);
method public boolean contentEquals(androidx.compose.runtime.collection.MutableVector<T> other);
method public void ensureCapacity(int capacity);
- method public T! first();
- method public inline T! first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+ method public T first();
+ method public inline T first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline T? firstOrNull();
method public inline T? firstOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public inline <R> R! fold(R? initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
- method public inline <R> R! foldIndexed(R? initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
- method public inline <R> R! foldRight(R? initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
- method public inline <R> R! foldRightIndexed(R? initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
+ method public inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
+ method public inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
+ method public inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
+ method public inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
method public inline void forEach(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
method public inline void forEachReversed(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
method public inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
- method public inline operator T! get(int index);
+ method public inline operator T get(int index);
method public inline kotlin.ranges.IntRange getIndices();
method public inline int getLastIndex();
method public int getSize();
- method public int indexOf(T? element);
+ method public int indexOf(T element);
method public inline int indexOfFirst(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline int indexOfLast(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public boolean isEmpty();
method public boolean isNotEmpty();
- method public T! last();
- method public inline T! last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public int lastIndexOf(T? element);
+ method public T last();
+ method public inline T last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+ method public int lastIndexOf(T element);
method public inline T? lastOrNull();
method public inline T? lastOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public inline <reified R> R![] map(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public inline <reified R> R![] mapIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapIndexedNotNull(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapNotNull(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
- method public inline operator void minusAssign(T? element);
- method public inline operator void plusAssign(T? element);
- method public boolean remove(T? element);
+ method public inline operator void minusAssign(T element);
+ method public inline operator void plusAssign(T element);
+ method public boolean remove(T element);
method public boolean removeAll(java.util.List<? extends T> elements);
method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
method public boolean removeAll(java.util.Collection<? extends T> elements);
- method public T! removeAt(int index);
+ method public T removeAt(int index);
method public void removeRange(int start, int end);
method public boolean retainAll(java.util.Collection<? extends T> elements);
method public inline boolean reversedAny(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
- method public operator T! set(int index, T? element);
+ method public operator T set(int index, T element);
method public void sortWith(java.util.Comparator<T> comparator);
method public inline int sumBy(kotlin.jvm.functions.Function1<? super T,java.lang.Integer> selector);
method @kotlin.PublishedApi internal Void throwNoSuchElementException();
@@ -762,6 +762,11 @@
package androidx.compose.runtime.snapshots {
+ @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.PROPERTY) public @interface AutoboxingStateValueProperty {
+ method public abstract String preferredPropertyName();
+ property public abstract String preferredPropertyName;
+ }
+
public class MutableSnapshot extends androidx.compose.runtime.snapshots.Snapshot {
method public androidx.compose.runtime.snapshots.SnapshotApplyResult apply();
method public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? getReadObserver();
@@ -783,7 +788,7 @@
public abstract sealed class Snapshot {
method public void dispose();
- method public final inline <T> T! enter(kotlin.jvm.functions.Function0<? extends T> block);
+ method public final inline <T> T enter(kotlin.jvm.functions.Function0<? extends T> block);
method public int getId();
method public abstract boolean getReadOnly();
method public abstract androidx.compose.runtime.snapshots.Snapshot getRoot();
@@ -800,9 +805,9 @@
public static final class Snapshot.Companion {
method @kotlin.PublishedApi internal androidx.compose.runtime.snapshots.Snapshot createNonObservableSnapshot();
method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
- method public inline <T> T! global(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
method public void notifyObjectsInitialized();
- method public <T> T! observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
+ method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
method public androidx.compose.runtime.snapshots.ObserverHandle registerGlobalWriteObserver(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> observer);
method @kotlin.PublishedApi internal androidx.compose.runtime.snapshots.Snapshot? removeCurrent();
@@ -810,8 +815,8 @@
method public void sendApplyNotifications();
method public androidx.compose.runtime.snapshots.MutableSnapshot takeMutableSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver);
method public androidx.compose.runtime.snapshots.Snapshot takeSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
- method public inline <R> R! withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
- method public inline <T> T! withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
+ method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
+ method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
property public final androidx.compose.runtime.snapshots.Snapshot current;
}
@@ -849,10 +854,10 @@
method @kotlin.PublishedApi internal static void notifyWrite(androidx.compose.runtime.snapshots.Snapshot snapshot, androidx.compose.runtime.snapshots.StateObject state);
method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state);
method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
- method @kotlin.PublishedApi internal static inline <T> T! sync(kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
- method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R! writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method @kotlin.PublishedApi internal static inline <T> T sync(kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
method @kotlin.PublishedApi internal static <T extends androidx.compose.runtime.snapshots.StateRecord> T writableRecord(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
field @kotlin.PublishedApi internal static final Object lock;
field @kotlin.PublishedApi internal static final androidx.compose.runtime.snapshots.Snapshot snapshotInitializer;
@@ -865,29 +870,29 @@
@androidx.compose.runtime.Stable public final class SnapshotStateList<T> implements kotlin.jvm.internal.markers.KMutableList java.util.List<T> androidx.compose.runtime.snapshots.StateObject {
ctor public SnapshotStateList();
- method public boolean add(T? element);
- method public void add(int index, T? element);
+ method public boolean add(T element);
+ method public void add(int index, T element);
method public boolean addAll(int index, java.util.Collection<? extends T> elements);
method public boolean addAll(java.util.Collection<? extends T> elements);
method public void clear();
- method public boolean contains(T? element);
+ method public boolean contains(T element);
method public boolean containsAll(java.util.Collection<E!> elements);
- method public T! get(int index);
+ method public T get(int index);
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public int getSize();
- method public int indexOf(T? element);
+ method public int indexOf(T element);
method public boolean isEmpty();
method public java.util.Iterator<T> iterator();
- method public int lastIndexOf(T? element);
+ method public int lastIndexOf(T element);
method public java.util.ListIterator<T> listIterator();
method public java.util.ListIterator<T> listIterator(int index);
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
- method public boolean remove(T? element);
+ method public boolean remove(T element);
method public boolean removeAll(java.util.Collection<E!> elements);
- method public T! removeAt(int index);
+ method public T removeAt(int index);
method public void removeRange(int fromIndex, int toIndex);
method public boolean retainAll(java.util.Collection<E!> elements);
- method public T! set(int index, T? element);
+ method public T set(int index, T element);
method public java.util.List<T> subList(int fromIndex, int toIndex);
method public java.util.List<T> toList();
property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
@@ -897,9 +902,9 @@
@androidx.compose.runtime.Stable public final class SnapshotStateMap<K, V> implements kotlin.jvm.internal.markers.KMutableMap java.util.Map<K,V> androidx.compose.runtime.snapshots.StateObject {
ctor public SnapshotStateMap();
method public void clear();
- method public boolean containsKey(K? key);
- method public boolean containsValue(V? value);
- method public V? get(Object? key);
+ method public boolean containsKey(K key);
+ method public boolean containsValue(V value);
+ method public V? get(Object key);
method public java.util.Set<java.util.Map.Entry<K,V>> getEntries();
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public java.util.Set<K> getKeys();
@@ -907,9 +912,9 @@
method public java.util.Collection<V> getValues();
method public boolean isEmpty();
method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
- method public V? put(K? key, V? value);
+ method public V? put(K key, V value);
method public void putAll(java.util.Map<? extends K,? extends V> from);
- method public V? remove(Object? key);
+ method public V? remove(Object key);
method public java.util.Map<K,V> toMap();
property public java.util.Set<java.util.Map.Entry<K,V>> entries;
property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
index 723f147..71de1aa 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
@@ -19,6 +19,7 @@
package androidx.compose.runtime
import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
import androidx.compose.runtime.snapshots.StateObject
@@ -55,6 +56,7 @@
@Stable
@JvmDefaultWithCompatibility
interface DoubleState : State<Double> {
+ @AutoboxingStateValueProperty("doubleValue")
override val value: Double
@Suppress("AutoBoxing") get() = doubleValue
@@ -83,6 +85,7 @@
@Stable
@JvmDefaultWithCompatibility
interface MutableDoubleState : DoubleState, MutableState<Double> {
+ @AutoboxingStateValueProperty("doubleValue")
override var value: Double
@Suppress("AutoBoxing") get() = doubleValue
set(value) { doubleValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
index a31d255..b48a3fb 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
@@ -18,6 +18,7 @@
@file:JvmMultifileClass
package androidx.compose.runtime
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
import androidx.compose.runtime.snapshots.StateObject
@@ -54,6 +55,7 @@
@Stable
@JvmDefaultWithCompatibility
interface FloatState : State<Float> {
+ @AutoboxingStateValueProperty("floatValue")
override val value: Float
@Suppress("AutoBoxing") get() = floatValue
@@ -79,6 +81,7 @@
@Stable
@JvmDefaultWithCompatibility
interface MutableFloatState : FloatState, MutableState<Float> {
+ @AutoboxingStateValueProperty("floatValue")
override var value: Float
@Suppress("AutoBoxing") get() = floatValue
set(value) { floatValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
index 4520c42..785f9b7 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
@@ -18,6 +18,7 @@
@file:JvmMultifileClass
package androidx.compose.runtime
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
import androidx.compose.runtime.snapshots.StateObject
@@ -54,6 +55,7 @@
@Stable
@JvmDefaultWithCompatibility
interface IntState : State<Int> {
+ @AutoboxingStateValueProperty("intValue")
override val value: Int
@Suppress("AutoBoxing") get() = intValue
@@ -79,6 +81,7 @@
@Stable
@JvmDefaultWithCompatibility
interface MutableIntState : IntState, MutableState<Int> {
+ @AutoboxingStateValueProperty("intValue")
override var value: Int
@Suppress("AutoBoxing") get() = intValue
set(value) { intValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
index f1869df..e129f42 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
@@ -19,6 +19,7 @@
package androidx.compose.runtime
import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
+import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
import androidx.compose.runtime.snapshots.StateObject
@@ -55,6 +56,7 @@
@Stable
@JvmDefaultWithCompatibility
interface LongState : State<Long> {
+ @AutoboxingStateValueProperty("longValue")
override val value: Long
@Suppress("AutoBoxing") get() = longValue
@@ -80,6 +82,7 @@
@Stable
@JvmDefaultWithCompatibility
interface MutableLongState : LongState, MutableState<Long> {
+ @AutoboxingStateValueProperty("longValue")
override var value: Long
@Suppress("AutoBoxing") get() = longValue
set(value) { longValue = value }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.kt
new file mode 100644
index 0000000..3f3a814
--- /dev/null
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/AutoboxingStateValueProperty.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.runtime.snapshots
+
+/**
+ * This annotation designates that a property on a [State] class will autobox when it is read from
+ * or assigned to. This is helpful for state APIs like [IntState], which define an alternative
+ * value property that does not box while maintaining compatibility with the generic
+ * [`State<T>`][State] API.
+ *
+ * Whenever a property that is annotated with `AutoboxingStateValueProperty` is accessed in code,
+ * it will be flagged with a warning and will suggest using an alternative, non-boxing property
+ * instead.
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(AnnotationTarget.PROPERTY)
+annotation class AutoboxingStateValueProperty(
+ /**
+ * An alternative, non-boxing property that can be used instead of the annotated property.
+ * The property indicated in this property should contain the exact same value as the annotated
+ * property and should be observed in Compose in the same way, meaning that the designated
+ * replacement property can serve as a drop-in replacement to the annotated property.
+ *
+ * This property name will be used for suggesting quick fixes. It must match the suggested
+ * property name exactly, including its case.
+ */
+ @Suppress("unused") // Used by lint
+ val preferredPropertyName: String
+)
diff --git a/compose/ui/ui-graphics/api/api_lint.ignore b/compose/ui/ui-graphics/api/api_lint.ignore
index 6f1ace9..476b5f2 100644
--- a/compose/ui/ui-graphics/api/api_lint.ignore
+++ b/compose/ui/ui-graphics/api/api_lint.ignore
@@ -43,6 +43,10 @@
Getter should be on the built object, not the builder: method androidx.compose.ui.graphics.vector.PathBuilder.getNodes()
+GetterSetterNames: androidx.compose.ui.graphics.ImageBitmap#getHasAlpha():
+ Getter for boolean property `hasAlpha` is named `getHasAlpha` but should match the property name. Use `@get:JvmName` to rename.
+
+
KotlinDefaultParameterOrder: androidx.compose.ui.graphics.Canvas#drawImageRect(androidx.compose.ui.graphics.ImageBitmap, long, long, long, long, androidx.compose.ui.graphics.Paint) parameter #1:
Parameter `srcOffset` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
KotlinDefaultParameterOrder: androidx.compose.ui.graphics.Canvas#drawImageRect(androidx.compose.ui.graphics.ImageBitmap, long, long, long, long, androidx.compose.ui.graphics.Paint) parameter #2:
@@ -59,16 +63,12 @@
androidx.compose.ui.graphics.vector.PathBuilder does not declare a `build()` method, but builder classes are expected to
-MissingNullability: androidx.compose.ui.graphics.PaintKt#Paint():
- Missing nullability on method `Paint` return
-
-
NotCloseable: androidx.compose.ui.graphics.AndroidPath:
- Classes that release resources (close()) should implement AutoClosable and CloseGuard: class androidx.compose.ui.graphics.AndroidPath
+ Classes that release resources (close()) should implement AutoCloseable and CloseGuard: class androidx.compose.ui.graphics.AndroidPath
NotCloseable: androidx.compose.ui.graphics.Path:
- Classes that release resources (close()) should implement AutoClosable and CloseGuard: class androidx.compose.ui.graphics.Path
+ Classes that release resources (close()) should implement AutoCloseable and CloseGuard: class androidx.compose.ui.graphics.Path
NotCloseable: androidx.compose.ui.graphics.vector.PathBuilder:
- Classes that release resources (close()) should implement AutoClosable and CloseGuard: class androidx.compose.ui.graphics.vector.PathBuilder
+ Classes that release resources (close()) should implement AutoCloseable and CloseGuard: class androidx.compose.ui.graphics.vector.PathBuilder
TopLevelBuilder: androidx.compose.ui.graphics.vector.PathBuilder:
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
index ab73407..e081e68 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
@@ -16,13 +16,22 @@
package androidx.compose.ui.graphics
+import android.graphics.ColorSpace
+import android.graphics.ColorSpace.Named
+import android.graphics.ColorSpace.Rgb
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.ui.graphics.ImageBitmapTest.ColorSpaceHelper.Companion.colorSpaceTestHelper
import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.compose.ui.graphics.colorspace.TransferParameters
+import androidx.compose.ui.graphics.colorspace.WhitePoint
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Test
import org.junit.runner.RunWith
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -45,4 +54,227 @@
assertFalse(image.hasAlpha)
assertEquals(cs, image.colorSpace)
}
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testSrgbColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.Srgb, // Compose
+ ColorSpace.get(Named.SRGB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testAcesColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.Aces, // Compose
+ ColorSpace.get(Named.ACES) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testAcescgColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.Acescg, // Compose
+ ColorSpace.get(Named.ACESCG) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testAdobeRgbColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.AdobeRgb, // Compose
+ ColorSpace.get(Named.ADOBE_RGB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testBt2020Colorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.Bt2020, // Compose
+ ColorSpace.get(Named.BT2020) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testBt709Colorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.Bt709, // Compose
+ ColorSpace.get(Named.BT709) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testCieLabColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.CieLab, // Compose
+ ColorSpace.get(Named.CIE_LAB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testCieXyzColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.CieXyz, // Compose
+ ColorSpace.get(Named.CIE_XYZ) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testDciP3Colorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.DciP3, // Compose
+ ColorSpace.get(Named.DCI_P3) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testDisplayP3Colorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.DisplayP3, // Compose
+ ColorSpace.get(Named.DISPLAY_P3) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testExtendedSrgbColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.ExtendedSrgb, // Compose
+ ColorSpace.get(Named.EXTENDED_SRGB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testLinearExtendedSrgbColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.LinearExtendedSrgb, // Compose
+ ColorSpace.get(Named.LINEAR_EXTENDED_SRGB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testLinearSrgbColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.LinearSrgb, // Compose
+ ColorSpace.get(Named.LINEAR_SRGB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testNtsc1953Colorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.Ntsc1953, // Compose
+ ColorSpace.get(Named.NTSC_1953) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testProPhotoRgbColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.ProPhotoRgb, // Compose
+ ColorSpace.get(Named.PRO_PHOTO_RGB) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testSmpteCColorspace() {
+ colorSpaceTestHelper(
+ ColorSpaces.SmpteC, // Compose
+ ColorSpace.get(Named.SMPTE_C) // Framework
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testUnknownColorspace3WhitePointValues() {
+ val name = "MyCustomColorSpace"
+ val whitePoint = floatArrayOf(1.0f, 2.0f, 3.0f)
+ val transferParameters = Rgb.TransferParameters(
+ 0.1, // a
+ 0.2, // b
+ 0.3, // c
+ 0.4, // d
+ 0.5, // e
+ 0.6, // f
+ 0.7 // g
+ )
+ val primaries = floatArrayOf(1f, 2f, 3f, 4f, 5f, 6f)
+ colorSpaceTestHelper(
+ androidx.compose.ui.graphics.colorspace.Rgb(
+ name = name,
+ primaries = primaries,
+ WhitePoint(1.0f, 2.0f, 3.0f),
+ TransferParameters(0.7, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
+ ),
+ Rgb(
+ name,
+ primaries,
+ whitePoint,
+ transferParameters
+ )
+ )
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun testUnknownColorspace2WhitePointValues() {
+ val name = "MyCustomColorSpace"
+ val whitePoint = floatArrayOf(1.0f, 2.0f)
+ val transferParameters = Rgb.TransferParameters(
+ 0.1, // a
+ 0.2, // b
+ 0.3, // c
+ 0.4, // d
+ 0.5, // e
+ 0.6, // f
+ 0.7 // g
+ )
+ val primaries = floatArrayOf(1f, 2f, 3f, 4f, 5f, 6f)
+
+ colorSpaceTestHelper(
+ androidx.compose.ui.graphics.colorspace.Rgb(
+ name = name,
+ primaries = primaries,
+ WhitePoint(1.0f, 2.0f),
+ TransferParameters(0.7, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
+ ),
+ Rgb(
+ name,
+ primaries,
+ whitePoint,
+ transferParameters
+ )
+ )
+ }
+
+ // Helper class to avoid NoSuchClassExceptions being thrown when tests are run on an older
+ // API level that does not understand ColorSpace APIs
+ internal class ColorSpaceHelper {
+ companion object {
+ @RequiresApi(Build.VERSION_CODES.O)
+ fun colorSpaceTestHelper(
+ composeColorSpace: androidx.compose.ui.graphics.colorspace.ColorSpace,
+ frameworkColorSpace: ColorSpace
+ ) {
+ with(Api26Bitmap) {
+ assertEquals(composeColorSpace, frameworkColorSpace.composeColorSpace())
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
index 3faf08c..2e7700c 100644
--- a/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
+++ b/compose/ui/ui-graphics/src/androidMain/kotlin/androidx/compose/ui/graphics/AndroidImageBitmap.android.kt
@@ -17,12 +17,16 @@
package androidx.compose.ui.graphics
import android.graphics.Bitmap
+import android.graphics.ColorSpace.Named
import android.os.Build
import android.util.DisplayMetrics
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresApi
import androidx.compose.ui.graphics.colorspace.ColorSpace
import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.compose.ui.graphics.colorspace.Rgb
+import androidx.compose.ui.graphics.colorspace.TransferParameters
+import androidx.compose.ui.graphics.colorspace.WhitePoint
/**
* Create an [ImageBitmap] from the given [Bitmap]. Note this does
@@ -184,7 +188,7 @@
* elimination during compilation time
*/
@RequiresApi(Build.VERSION_CODES.O)
-private object Api26Bitmap {
+internal object Api26Bitmap {
@DoNotInline
@JvmStatic
internal fun createBitmap(
@@ -214,67 +218,86 @@
@JvmStatic
internal fun ColorSpace.toFrameworkColorSpace(): android.graphics.ColorSpace {
val frameworkNamedSpace = when (this) {
- ColorSpaces.Srgb -> android.graphics.ColorSpace.Named.SRGB
- ColorSpaces.Aces -> android.graphics.ColorSpace.Named.ACES
- ColorSpaces.Acescg -> android.graphics.ColorSpace.Named.ACESCG
- ColorSpaces.AdobeRgb -> android.graphics.ColorSpace.Named.ADOBE_RGB
- ColorSpaces.Bt2020 -> android.graphics.ColorSpace.Named.BT2020
- ColorSpaces.Bt709 -> android.graphics.ColorSpace.Named.BT709
- ColorSpaces.CieLab -> android.graphics.ColorSpace.Named.CIE_LAB
- ColorSpaces.CieXyz -> android.graphics.ColorSpace.Named.CIE_XYZ
- ColorSpaces.DciP3 -> android.graphics.ColorSpace.Named.DCI_P3
- ColorSpaces.DisplayP3 -> android.graphics.ColorSpace.Named.DISPLAY_P3
- ColorSpaces.ExtendedSrgb -> android.graphics.ColorSpace.Named.EXTENDED_SRGB
+ ColorSpaces.Srgb -> Named.SRGB
+ ColorSpaces.Aces -> Named.ACES
+ ColorSpaces.Acescg -> Named.ACESCG
+ ColorSpaces.AdobeRgb -> Named.ADOBE_RGB
+ ColorSpaces.Bt2020 -> Named.BT2020
+ ColorSpaces.Bt709 -> Named.BT709
+ ColorSpaces.CieLab -> Named.CIE_LAB
+ ColorSpaces.CieXyz -> Named.CIE_XYZ
+ ColorSpaces.DciP3 -> Named.DCI_P3
+ ColorSpaces.DisplayP3 -> Named.DISPLAY_P3
+ ColorSpaces.ExtendedSrgb -> Named.EXTENDED_SRGB
ColorSpaces.LinearExtendedSrgb ->
- android.graphics.ColorSpace.Named.LINEAR_EXTENDED_SRGB
- ColorSpaces.LinearSrgb -> android.graphics.ColorSpace.Named.LINEAR_SRGB
- ColorSpaces.Ntsc1953 -> android.graphics.ColorSpace.Named.NTSC_1953
- ColorSpaces.ProPhotoRgb -> android.graphics.ColorSpace.Named.PRO_PHOTO_RGB
- ColorSpaces.SmpteC -> android.graphics.ColorSpace.Named.SMPTE_C
- else -> android.graphics.ColorSpace.Named.SRGB
+ Named.LINEAR_EXTENDED_SRGB
+ ColorSpaces.LinearSrgb -> Named.LINEAR_SRGB
+ ColorSpaces.Ntsc1953 -> Named.NTSC_1953
+ ColorSpaces.ProPhotoRgb -> Named.PRO_PHOTO_RGB
+ ColorSpaces.SmpteC -> Named.SMPTE_C
+ else -> Named.SRGB
}
return android.graphics.ColorSpace.get(frameworkNamedSpace)
}
@DoNotInline
@JvmStatic
- internal fun android.graphics.ColorSpace.composeColorSpace(): ColorSpace {
- return when (this) {
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.SRGB) ->
- ColorSpaces.Srgb
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.ACES) ->
- ColorSpaces.Aces
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.ACESCG) ->
- ColorSpaces.Acescg
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.ADOBE_RGB) ->
- ColorSpaces.AdobeRgb
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.BT2020) ->
- ColorSpaces.Bt2020
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.BT709) ->
- ColorSpaces.Bt709
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.CIE_LAB) ->
- ColorSpaces.CieLab
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.CIE_XYZ) ->
- ColorSpaces.CieXyz
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.DCI_P3) ->
- ColorSpaces.DciP3
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.DISPLAY_P3) ->
- ColorSpaces.DisplayP3
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.EXTENDED_SRGB) ->
- ColorSpaces.ExtendedSrgb
- android.graphics.ColorSpace.get(
- android.graphics.ColorSpace.Named.LINEAR_EXTENDED_SRGB
- ) ->
- ColorSpaces.LinearExtendedSrgb
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.LINEAR_SRGB) ->
- ColorSpaces.LinearSrgb
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.NTSC_1953) ->
- ColorSpaces.Ntsc1953
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.PRO_PHOTO_RGB) ->
- ColorSpaces.ProPhotoRgb
- android.graphics.ColorSpace.get(android.graphics.ColorSpace.Named.SMPTE_C) ->
- ColorSpaces.SmpteC
- else -> ColorSpaces.Srgb
+ fun android.graphics.ColorSpace.composeColorSpace(): ColorSpace {
+ return when (this.id) {
+ Named.SRGB.ordinal -> ColorSpaces.Srgb
+ Named.ACES.ordinal -> ColorSpaces.Aces
+ Named.ACESCG.ordinal -> ColorSpaces.Acescg
+ Named.ADOBE_RGB.ordinal -> ColorSpaces.AdobeRgb
+ Named.BT2020.ordinal -> ColorSpaces.Bt2020
+ Named.BT709.ordinal -> ColorSpaces.Bt709
+ Named.CIE_LAB.ordinal -> ColorSpaces.CieLab
+ Named.CIE_XYZ.ordinal -> ColorSpaces.CieXyz
+ Named.DCI_P3.ordinal -> ColorSpaces.DciP3
+ Named.DISPLAY_P3.ordinal -> ColorSpaces.DisplayP3
+ Named.EXTENDED_SRGB.ordinal -> ColorSpaces.ExtendedSrgb
+ Named.LINEAR_EXTENDED_SRGB.ordinal -> ColorSpaces.LinearExtendedSrgb
+ Named.LINEAR_SRGB.ordinal -> ColorSpaces.LinearSrgb
+ Named.NTSC_1953.ordinal -> ColorSpaces.Ntsc1953
+ Named.PRO_PHOTO_RGB.ordinal -> ColorSpaces.ProPhotoRgb
+ Named.SMPTE_C.ordinal -> ColorSpaces.SmpteC
+ else -> {
+ if (this is android.graphics.ColorSpace.Rgb) {
+ val transferParams = this.transferParameters
+ val whitePoint = if (this.whitePoint.size == 3) {
+ WhitePoint(this.whitePoint[0], this.whitePoint[1], this.whitePoint[2])
+ } else {
+ WhitePoint(this.whitePoint[0], this.whitePoint[1])
+ }
+
+ val composeTransferParams = if (transferParams != null) {
+ TransferParameters(
+ gamma = transferParams.g,
+ a = transferParams.a,
+ b = transferParams.b,
+ c = transferParams.c,
+ d = transferParams.d,
+ e = transferParams.e,
+ f = transferParams.f
+ )
+ } else {
+ null
+ }
+ Rgb(
+ name = this.name,
+ primaries = this.primaries,
+ whitePoint = whitePoint,
+ transform = this.transform,
+ oetf = { x -> this.oetf.applyAsDouble(x) },
+ eotf = { x -> this.eotf.applyAsDouble(x) },
+ min = this.getMinValue(0),
+ max = this.getMaxValue(0),
+ transferParameters = composeTransferParams,
+ id = this.id
+ )
+ } else {
+ ColorSpaces.Srgb
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/compose/ui/ui-inspection/build.gradle b/compose/ui/ui-inspection/build.gradle
index b8db908..d7db14f 100644
--- a/compose/ui/ui-inspection/build.gradle
+++ b/compose/ui/ui-inspection/build.gradle
@@ -45,6 +45,7 @@
androidTestImplementation(libs.kotlinStdlib)
androidTestImplementation(libs.kotlinCoroutinesAndroid)
androidTestImplementation(libs.testCore)
+ androidTestImplementation(project(":compose:foundation:foundation-layout"))
androidTestImplementation(project(":compose:ui:ui-tooling"))
androidTestImplementation(project(":compose:ui:ui-tooling-data"))
androidTestImplementation(project(":compose:ui:ui"))
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
index f78d114..d68d55d 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/inspector/LayoutInspectorTreeTest.kt
@@ -97,7 +97,6 @@
import kotlin.math.roundToInt
import org.junit.After
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -165,7 +164,6 @@
assertThat(DEBUG).isFalse()
}
- @Ignore // b/273151077
@Test
fun buildTree() {
val slotTableRecord = CompositionDataRecord.create()
@@ -246,7 +244,6 @@
}
}
- @Ignore // b/273151077
@Test
fun buildTreeWithTransformedText() {
val slotTableRecord = CompositionDataRecord.create()
@@ -316,16 +313,13 @@
val nodes = builder.convert(view)
dumpNodes(nodes, view, builder)
- if (DEBUG) {
- validate(nodes, builder) {
- node("Box", children = listOf("ModalDrawer"))
- node("ModalDrawer", children = listOf("Column", "Text"))
- node("Column", children = listOf("Text", "Button"))
- node("Text")
- node("Button", children = listOf("Text"))
- node("Text")
- node("Text")
- }
+ validate(nodes, builder) {
+ node("ModalDrawer", isRenderNode = true, children = listOf("Column", "Text"))
+ node("Column", inlined = true, children = listOf("Text", "Button"))
+ node("Text", isRenderNode = true)
+ node("Button", isRenderNode = true, children = listOf("Text"))
+ node("Text", isRenderNode = true)
+ node("Text", isRenderNode = true)
}
assertThat(nodes.size).isEqualTo(1)
}
@@ -357,7 +351,6 @@
if (DEBUG) {
validate(nodes, builder) {
- node("Box", children = listOf("ModalDrawer"))
node("ModalDrawer", children = listOf("WithConstraints"))
node("WithConstraints", children = listOf("SubcomposeLayout"))
node("SubcomposeLayout", children = listOf("Box"))
@@ -468,7 +461,6 @@
assertThat(node?.id).isGreaterThan(0)
}
- @Ignore // b/273151077
@Test
fun testSemantics() {
val slotTableRecord = CompositionDataRecord.create()
@@ -521,7 +513,6 @@
}
}
- @Ignore // b/273151077
@Test
fun testDialog() {
val slotTableRecord = CompositionDataRecord.create()
@@ -594,7 +585,6 @@
}
}
- @Ignore // b/273151077
@Test
fun testPopup() {
val slotTableRecord = CompositionDataRecord.create()
@@ -826,7 +816,6 @@
}
// WARNING: End formatted section
- @Ignore // b/273151077
@Test
fun testLineNumbers() {
// WARNING: The formatting of the lines below here affect test results.
@@ -1038,6 +1027,7 @@
assertWithMessage("No such node found: $name").that(nodeIterator.hasNext()).isTrue()
val node = nodeIterator.next()
assertThat(node.name).isEqualTo(name)
+ assertThat(node.anchorId).isNotEqualTo(UNDEFINED_ID)
val message = "Node: $name"
assertWithMessage(message).that(node.children.map { it.name })
.containsExactlyElementsIn(children).inOrder()
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
index 4819ad7..2dd9d34 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/InspectorNode.kt
@@ -230,7 +230,10 @@
fun shallowCopy(node: InspectorNode): MutableInspectorNode = apply {
id = node.id
- viewId = node.viewId
+ key = node.key
+ anchorId = node.anchorId
+ mergedSemantics.addAll(node.mergedSemantics)
+ unmergedSemantics.addAll(node.unmergedSemantics)
name = node.name
fileName = node.fileName
packageHash = node.packageHash
@@ -240,9 +243,8 @@
box = node.box
bounds = node.bounds
inlined = node.inlined
- mergedSemantics.addAll(node.mergedSemantics)
- unmergedSemantics.addAll(node.unmergedSemantics)
parameters.addAll(node.parameters)
+ viewId = node.viewId
children.addAll(node.children)
}
diff --git a/compose/ui/ui-test-junit4/api/current.txt b/compose/ui/ui-test-junit4/api/current.txt
index 94a0fe4..d860c74 100644
--- a/compose/ui/ui-test-junit4/api/current.txt
+++ b/compose/ui/ui-test-junit4/api/current.txt
@@ -12,8 +12,8 @@
method public androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodes(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
method public androidx.compose.ui.test.SemanticsNodeInteraction onNode(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
@@ -45,8 +45,8 @@
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.test.MainTestClock getMainClock();
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
method public void waitUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
diff --git a/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt b/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
index 53f3965..2dfc3a1 100644
--- a/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-test-junit4/api/public_plus_experimental_current.txt
@@ -10,7 +10,7 @@
ctor public AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext);
method protected abstract A? getActivity();
method public final androidx.compose.ui.test.AndroidComposeUiTest<A> getTest();
- method public final <R> R! runTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,? extends R> block);
+ method public final <R> R runTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,? extends R> block);
property protected abstract A? activity;
property public final androidx.compose.ui.test.AndroidComposeUiTest<A> test;
}
@@ -20,8 +20,8 @@
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.test.MainTestClock getMainClock();
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
@@ -68,8 +68,8 @@
method public androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodes(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
method public androidx.compose.ui.test.SemanticsNodeInteraction onNode(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
@@ -109,8 +109,8 @@
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.test.MainTestClock getMainClock();
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
method public void waitUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
diff --git a/compose/ui/ui-test-junit4/api/restricted_current.txt b/compose/ui/ui-test-junit4/api/restricted_current.txt
index 94a0fe4..d860c74 100644
--- a/compose/ui/ui-test-junit4/api/restricted_current.txt
+++ b/compose/ui/ui-test-junit4/api/restricted_current.txt
@@ -12,8 +12,8 @@
method public androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodes(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
method public androidx.compose.ui.test.SemanticsNodeInteraction onNode(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
@@ -45,8 +45,8 @@
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.test.MainTestClock getMainClock();
method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
- method public <T> T! runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
method public void waitForIdle();
method public void waitUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
diff --git a/compose/ui/ui-test/api/api_lint.ignore b/compose/ui/ui-test/api/api_lint.ignore
index 4eff534..7466e22 100644
--- a/compose/ui/ui-test/api/api_lint.ignore
+++ b/compose/ui/ui-test/api/api_lint.ignore
@@ -1,3 +1,5 @@
// Baseline format: 1.0
-GetterSetterNames: androidx.compose.ui.test.MainTestClock#getAutoAdvance():
- Symmetric method for `setAutoAdvance` must be named `isAutoAdvance`; was `getAutoAdvance`
+GetterSetterNames: androidx.compose.ui.test.TestMonotonicFrameClock#getHasAwaiters():
+ Getter for boolean property `hasAwaiters` is named `getHasAwaiters` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field MainTestClock.autoAdvance:
+ Invalid name for boolean property `autoAdvance`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-test/api/current.ignore b/compose/ui/ui-test/api/current.ignore
index 6cf936b..5af1fc7 100644
--- a/compose/ui/ui-test/api/current.ignore
+++ b/compose/ui/ui-test/api/current.ignore
@@ -5,6 +5,10 @@
Method androidx.compose.ui.test.ActionsKt.performSemanticsAction has changed return type from androidx.compose.ui.test.SemanticsNodeInteraction to void
+InvalidNullConversion: androidx.compose.ui.test.SemanticsMatcher.Companion#expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter expectedValue in androidx.compose.ui.test.SemanticsMatcher.Companion.expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue)
+
+
RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>):
Removed deprecated method androidx.compose.ui.test.ActionsKt.performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction,androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>,kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>)
RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<? extends java.lang.Boolean>>>):
diff --git a/compose/ui/ui-test/api/current.txt b/compose/ui/ui-test/api/current.txt
index 684e9c8..88c2a89 100644
--- a/compose/ui/ui-test/api/current.txt
+++ b/compose/ui/ui-test/api/current.txt
@@ -305,7 +305,7 @@
}
public static final class SemanticsMatcher.Companion {
- method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? expectedValue);
+ method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue);
method public <T> androidx.compose.ui.test.SemanticsMatcher keyIsDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
method public <T> androidx.compose.ui.test.SemanticsMatcher keyNotDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
}
diff --git a/compose/ui/ui-test/api/public_plus_experimental_current.txt b/compose/ui/ui-test/api/public_plus_experimental_current.txt
index 219da1d..304fcbb 100644
--- a/compose/ui/ui-test/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-test/api/public_plus_experimental_current.txt
@@ -384,7 +384,7 @@
}
public static final class SemanticsMatcher.Companion {
- method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? expectedValue);
+ method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue);
method public <T> androidx.compose.ui.test.SemanticsMatcher keyIsDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
method public <T> androidx.compose.ui.test.SemanticsMatcher keyNotDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
}
@@ -437,7 +437,7 @@
@androidx.compose.ui.test.InternalTestApi public interface TestOwner {
method public androidx.compose.ui.test.MainTestClock getMainClock();
method public java.util.Set<androidx.compose.ui.node.RootForTest> getRoots(boolean atLeastOneRootExpected);
- method public <T> T! runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+ method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
property public abstract androidx.compose.ui.test.MainTestClock mainClock;
}
diff --git a/compose/ui/ui-test/api/restricted_current.ignore b/compose/ui/ui-test/api/restricted_current.ignore
index 6cf936b..5af1fc7 100644
--- a/compose/ui/ui-test/api/restricted_current.ignore
+++ b/compose/ui/ui-test/api/restricted_current.ignore
@@ -5,6 +5,10 @@
Method androidx.compose.ui.test.ActionsKt.performSemanticsAction has changed return type from androidx.compose.ui.test.SemanticsNodeInteraction to void
+InvalidNullConversion: androidx.compose.ui.test.SemanticsMatcher.Companion#expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter expectedValue in androidx.compose.ui.test.SemanticsMatcher.Companion.expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue)
+
+
RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>):
Removed deprecated method androidx.compose.ui.test.ActionsKt.performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction,androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>>,kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit>)
RemovedDeprecatedMethod: androidx.compose.ui.test.ActionsKt#performSemanticsActionUnit(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<? extends java.lang.Boolean>>>):
diff --git a/compose/ui/ui-test/api/restricted_current.txt b/compose/ui/ui-test/api/restricted_current.txt
index 1305308..e62c3ee 100644
--- a/compose/ui/ui-test/api/restricted_current.txt
+++ b/compose/ui/ui-test/api/restricted_current.txt
@@ -306,7 +306,7 @@
}
public static final class SemanticsMatcher.Companion {
- method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? expectedValue);
+ method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue);
method public <T> androidx.compose.ui.test.SemanticsMatcher keyIsDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
method public <T> androidx.compose.ui.test.SemanticsMatcher keyNotDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
}
diff --git a/compose/ui/ui-text-google-fonts/api/api_lint.ignore b/compose/ui/ui-text-google-fonts/api/api_lint.ignore
new file mode 100644
index 0000000..1cf64ad
--- /dev/null
+++ b/compose/ui/ui-text-google-fonts/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field GoogleFont.bestEffort:
+ Invalid name for boolean property `bestEffort`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-text/api/api_lint.ignore b/compose/ui/ui-text/api/api_lint.ignore
index 65c788e..734b4f8 100644
--- a/compose/ui/ui-text/api/api_lint.ignore
+++ b/compose/ui/ui-text/api/api_lint.ignore
@@ -25,6 +25,36 @@
Getter should be on the built object, not the builder: method androidx.compose.ui.text.AnnotatedString.Builder.getLength()
+GetterSetterNames: androidx.compose.ui.text.MultiParagraphIntrinsics#getHasStaleResolvedFonts():
+ Getter for boolean property `hasStaleResolvedFonts` is named `getHasStaleResolvedFonts` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.text.ParagraphIntrinsics#getHasStaleResolvedFonts():
+ Getter for boolean property `hasStaleResolvedFonts` is named `getHasStaleResolvedFonts` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.text.TextLayoutResult#getHasVisualOverflow():
+ Getter for boolean property `hasVisualOverflow` is named `getHasVisualOverflow` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field FontVariation.Setting.needsDensity:
+ Invalid name for boolean property `needsDensity`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ImeOptions.autoCorrect:
+ Invalid name for boolean property `autoCorrect`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ImeOptions.singleLine:
+ Invalid name for boolean property `singleLine`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field MultiParagraph.didExceedMaxLines:
+ Invalid name for boolean property `didExceedMaxLines`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Paragraph.didExceedMaxLines:
+ Invalid name for boolean property `didExceedMaxLines`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PlatformParagraphStyle.includeFontPadding:
+ Invalid name for boolean property `includeFontPadding`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextLayoutInput.softWrap:
+ Invalid name for boolean property `softWrap`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextLayoutResult.didOverflowHeight:
+ Invalid name for boolean property `didOverflowHeight`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextLayoutResult.didOverflowWidth:
+ Invalid name for boolean property `didOverflowWidth`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextRange.collapsed:
+ Invalid name for boolean property `collapsed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TextRange.reversed:
+ Invalid name for boolean property `reversed`. Should start with one of `has`, `can`, `should`, `is`.
+
+
KotlinDefaultParameterOrder: androidx.compose.ui.text.ParagraphIntrinsicsKt#ParagraphIntrinsics(String, androidx.compose.ui.text.TextStyle, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>>, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>>, androidx.compose.ui.unit.Density, androidx.compose.ui.text.font.FontFamily.Resolver) parameter #2:
Parameter `spanStyles` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
KotlinDefaultParameterOrder: androidx.compose.ui.text.ParagraphIntrinsicsKt#ParagraphIntrinsics(String, androidx.compose.ui.text.TextStyle, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>>, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>>, androidx.compose.ui.unit.Density, androidx.compose.ui.text.font.FontFamily.Resolver) parameter #3:
diff --git a/compose/ui/ui-text/api/current.ignore b/compose/ui/ui-text/api/current.ignore
index ae0c856..7670599 100644
--- a/compose/ui/ui-text/api/current.ignore
+++ b/compose/ui/ui-text/api/current.ignore
@@ -3,5 +3,11 @@
Method androidx.compose.ui.text.AnnotatedString.Builder.append has changed return type from androidx.compose.ui.text.AnnotatedString.Builder to void
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end)
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int, String) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end, String tag)
+
+
RemovedDeprecatedMethod: androidx.compose.ui.text.AnnotatedString.Builder#deprecated_append_returning_void(char):
Removed deprecated method androidx.compose.ui.text.AnnotatedString.Builder.deprecated_append_returning_void(char)
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index 5438f14..f05e380 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -52,19 +52,19 @@
}
@androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
- ctor public AnnotatedString.Range(T? item, int start, int end, String tag);
- ctor public AnnotatedString.Range(T? item, int start, int end);
- method public T! component1();
+ ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+ ctor public AnnotatedString.Range(T item, int start, int end);
+ method public T component1();
method public int component2();
method public int component3();
method public String component4();
method public androidx.compose.ui.text.AnnotatedString.Range<T> copy(T! item, int start, int end, String tag);
method public int getEnd();
- method public T! getItem();
+ method public T getItem();
method public int getStart();
method public String getTag();
property public final int end;
- property public final T! item;
+ property public final T item;
property public final int start;
property public final String tag;
}
diff --git a/compose/ui/ui-text/api/public_plus_experimental_current.txt b/compose/ui/ui-text/api/public_plus_experimental_current.txt
index 60ccba7..c7477c0 100644
--- a/compose/ui/ui-text/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-text/api/public_plus_experimental_current.txt
@@ -56,19 +56,19 @@
}
@androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
- ctor public AnnotatedString.Range(T? item, int start, int end, String tag);
- ctor public AnnotatedString.Range(T? item, int start, int end);
- method public T! component1();
+ ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+ ctor public AnnotatedString.Range(T item, int start, int end);
+ method public T component1();
method public int component2();
method public int component3();
method public String component4();
method public androidx.compose.ui.text.AnnotatedString.Range<T> copy(T! item, int start, int end, String tag);
method public int getEnd();
- method public T! getItem();
+ method public T getItem();
method public int getStart();
method public String getTag();
property public final int end;
- property public final T! item;
+ property public final T item;
property public final int start;
property public final String tag;
}
diff --git a/compose/ui/ui-text/api/restricted_current.ignore b/compose/ui/ui-text/api/restricted_current.ignore
index ae0c856..7670599 100644
--- a/compose/ui/ui-text/api/restricted_current.ignore
+++ b/compose/ui/ui-text/api/restricted_current.ignore
@@ -3,5 +3,11 @@
Method androidx.compose.ui.text.AnnotatedString.Builder.append has changed return type from androidx.compose.ui.text.AnnotatedString.Builder to void
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end)
+InvalidNullConversion: androidx.compose.ui.text.AnnotatedString.Range#Range(T, int, int, String) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter item in androidx.compose.ui.text.AnnotatedString.Range(T item, int start, int end, String tag)
+
+
RemovedDeprecatedMethod: androidx.compose.ui.text.AnnotatedString.Builder#deprecated_append_returning_void(char):
Removed deprecated method androidx.compose.ui.text.AnnotatedString.Builder.deprecated_append_returning_void(char)
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index 5438f14..f05e380 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -52,19 +52,19 @@
}
@androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
- ctor public AnnotatedString.Range(T? item, int start, int end, String tag);
- ctor public AnnotatedString.Range(T? item, int start, int end);
- method public T! component1();
+ ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+ ctor public AnnotatedString.Range(T item, int start, int end);
+ method public T component1();
method public int component2();
method public int component3();
method public String component4();
method public androidx.compose.ui.text.AnnotatedString.Range<T> copy(T! item, int start, int end, String tag);
method public int getEnd();
- method public T! getItem();
+ method public T getItem();
method public int getStart();
method public String getTag();
property public final int end;
- property public final T! item;
+ property public final T item;
property public final int start;
property public final String tag;
}
diff --git a/compose/ui/ui-tooling-data/api/api_lint.ignore b/compose/ui/ui-tooling-data/api/api_lint.ignore
new file mode 100644
index 0000000..1d26bba
--- /dev/null
+++ b/compose/ui/ui-tooling-data/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+GetterSetterNames: field ParameterInformation.compared:
+ Invalid name for boolean property `compared`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ParameterInformation.fromDefault:
+ Invalid name for boolean property `fromDefault`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ParameterInformation.stable:
+ Invalid name for boolean property `stable`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ParameterInformation.static:
+ Invalid name for boolean property `static`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-tooling-preview/api/api_lint.ignore b/compose/ui/ui-tooling-preview/api/api_lint.ignore
new file mode 100644
index 0000000..c8656ca
--- /dev/null
+++ b/compose/ui/ui-tooling-preview/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+GetterSetterNames: field Preview.showBackground:
+ Invalid name for boolean property `showBackground`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Preview.showSystemUi:
+ Invalid name for boolean property `showSystemUi`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/compose/ui/ui-tooling/api/current.ignore b/compose/ui/ui-tooling/api/current.ignore
new file mode 100644
index 0000000..5b8f04a
--- /dev/null
+++ b/compose/ui/ui-tooling/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.tooling.animation.ToolingState#ToolingState(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter default in androidx.compose.ui.tooling.animation.ToolingState(T default)
diff --git a/compose/ui/ui-tooling/api/current.txt b/compose/ui/ui-tooling/api/current.txt
index 94b79be..486b41e 100644
--- a/compose/ui/ui-tooling/api/current.txt
+++ b/compose/ui/ui-tooling/api/current.txt
@@ -10,10 +10,10 @@
package androidx.compose.ui.tooling.animation {
public final class ToolingState<T> implements androidx.compose.runtime.State<T> {
- ctor public ToolingState(T? default);
- method public T! getValue();
+ ctor public ToolingState(T default);
+ method public T getValue();
method public void setValue(T!);
- property public T! value;
+ property public T value;
}
}
diff --git a/compose/ui/ui-tooling/api/public_plus_experimental_current.txt b/compose/ui/ui-tooling/api/public_plus_experimental_current.txt
index e9656ce..df56c2d 100644
--- a/compose/ui/ui-tooling/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-tooling/api/public_plus_experimental_current.txt
@@ -15,10 +15,10 @@
package androidx.compose.ui.tooling.animation {
public final class ToolingState<T> implements androidx.compose.runtime.State<T> {
- ctor public ToolingState(T? default);
- method public T! getValue();
+ ctor public ToolingState(T default);
+ method public T getValue();
method public void setValue(T!);
- property public T! value;
+ property public T value;
}
}
diff --git a/compose/ui/ui-tooling/api/restricted_current.ignore b/compose/ui/ui-tooling/api/restricted_current.ignore
new file mode 100644
index 0000000..5b8f04a
--- /dev/null
+++ b/compose/ui/ui-tooling/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.tooling.animation.ToolingState#ToolingState(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter default in androidx.compose.ui.tooling.animation.ToolingState(T default)
diff --git a/compose/ui/ui-tooling/api/restricted_current.txt b/compose/ui/ui-tooling/api/restricted_current.txt
index 94b79be..486b41e 100644
--- a/compose/ui/ui-tooling/api/restricted_current.txt
+++ b/compose/ui/ui-tooling/api/restricted_current.txt
@@ -10,10 +10,10 @@
package androidx.compose.ui.tooling.animation {
public final class ToolingState<T> implements androidx.compose.runtime.State<T> {
- ctor public ToolingState(T? default);
- method public T! getValue();
+ ctor public ToolingState(T default);
+ method public T getValue();
method public void setValue(T!);
- property public T! value;
+ property public T value;
}
}
diff --git a/compose/ui/ui-unit/api/api_lint.ignore b/compose/ui/ui-unit/api/api_lint.ignore
index c473df8..2865c78 100644
--- a/compose/ui/ui-unit/api/api_lint.ignore
+++ b/compose/ui/ui-unit/api/api_lint.ignore
@@ -1,3 +1,13 @@
// Baseline format: 1.0
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasBoundedHeight():
+ Getter for boolean property `hasBoundedHeight` is named `getHasBoundedHeight` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasBoundedWidth():
+ Getter for boolean property `hasBoundedWidth` is named `getHasBoundedWidth` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasFixedHeight():
+ Getter for boolean property `hasFixedHeight` is named `getHasFixedHeight` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.unit.Constraints#getHasFixedWidth():
+ Getter for boolean property `hasFixedWidth` is named `getHasFixedWidth` but should match the property name. Use `@get:JvmName` to rename.
+
+
KotlinOperator: androidx.compose.ui.unit.IntRect#contains(long):
Note that adding the `operator` keyword would allow calling this method using operator syntax
diff --git a/compose/ui/ui-util/api/current.txt b/compose/ui/ui-util/api/current.txt
index e80820a..5e5e30e 100644
--- a/compose/ui/ui-util/api/current.txt
+++ b/compose/ui/ui-util/api/current.txt
@@ -2,7 +2,7 @@
package androidx.compose.ui.util {
public final class AndroidTrace_androidKt {
- method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
public final class InlineClassHelperKt {
diff --git a/compose/ui/ui-util/api/public_plus_experimental_current.txt b/compose/ui/ui-util/api/public_plus_experimental_current.txt
index e80820a..5e5e30e 100644
--- a/compose/ui/ui-util/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-util/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
package androidx.compose.ui.util {
public final class AndroidTrace_androidKt {
- method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
public final class InlineClassHelperKt {
diff --git a/compose/ui/ui-util/api/restricted_current.txt b/compose/ui/ui-util/api/restricted_current.txt
index e80820a..5e5e30e 100644
--- a/compose/ui/ui-util/api/restricted_current.txt
+++ b/compose/ui/ui-util/api/restricted_current.txt
@@ -2,7 +2,7 @@
package androidx.compose.ui.util {
public final class AndroidTrace_androidKt {
- method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
public final class InlineClassHelperKt {
diff --git a/compose/ui/ui-viewbinding/api/current.txt b/compose/ui/ui-viewbinding/api/current.txt
index 07ba909..00c3178 100644
--- a/compose/ui/ui-viewbinding/api/current.txt
+++ b/compose/ui/ui-viewbinding/api/current.txt
@@ -3,6 +3,7 @@
public final class AndroidViewBindingKt {
method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+ method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onReset, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onRelease, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
}
}
diff --git a/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt b/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
index 07ba909..00c3178 100644
--- a/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-viewbinding/api/public_plus_experimental_current.txt
@@ -3,6 +3,7 @@
public final class AndroidViewBindingKt {
method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+ method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onReset, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onRelease, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
}
}
diff --git a/compose/ui/ui-viewbinding/api/restricted_current.txt b/compose/ui/ui-viewbinding/api/restricted_current.txt
index 07ba909..00c3178 100644
--- a/compose/ui/ui-viewbinding/api/restricted_current.txt
+++ b/compose/ui/ui-viewbinding/api/restricted_current.txt
@@ -3,6 +3,7 @@
public final class AndroidViewBindingKt {
method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+ method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onReset, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onRelease, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
}
}
diff --git a/compose/ui/ui-viewbinding/samples/build.gradle b/compose/ui/ui-viewbinding/samples/build.gradle
index 6510bbb..29fab3b 100644
--- a/compose/ui/ui-viewbinding/samples/build.gradle
+++ b/compose/ui/ui-viewbinding/samples/build.gradle
@@ -40,6 +40,7 @@
androidTestImplementation(libs.testRunner)
androidTestImplementation(libs.junit)
androidTestImplementation(libs.truth)
+ androidTestImplementation(libs.espressoCore)
}
androidx {
diff --git a/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/ReusableAndroidViewBindingTest.kt b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/ReusableAndroidViewBindingTest.kt
new file mode 100644
index 0000000..2561853
--- /dev/null
+++ b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/ReusableAndroidViewBindingTest.kt
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.samples
+
+import android.widget.Button
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.text.BasicText
+import androidx.compose.runtime.ReusableContent
+import androidx.compose.runtime.ReusableContentHost
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.movableContentOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewbinding.samples.R
+import androidx.compose.ui.viewbinding.samples.databinding.SampleButtonLayoutBinding
+import androidx.compose.ui.viewbinding.samples.databinding.TestFragmentLayoutBinding
+import androidx.compose.ui.viewinterop.AndroidViewBinding
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE
+import androidx.test.espresso.matcher.ViewMatchers.withClassName
+import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import org.hamcrest.Matchers.`is`
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class ReusableAndroidViewBindingTest {
+
+ @get:Rule
+ val rule = createAndroidComposeRule<EmptyFragmentActivity>()
+
+ @Test
+ fun testViewIsReused_whenMovedAndUpdated() {
+ val events = mutableListOf<String>()
+ var slotWithContent by mutableStateOf(0)
+ val movableContext = movableContentOf {
+ AndroidViewBinding(
+ factory = { inflater, parent, attachToParent ->
+ events += "inflate"
+ SampleButtonLayoutBinding.inflate(inflater, parent, attachToParent)
+ },
+ modifier = Modifier.heightIn(max = 200.dp),
+ onReset = {
+ events += "reset"
+ myButton.text = null
+ },
+ onRelease = { events += "release" },
+ update = {
+ events += "update"
+ myButton.text = "Button in slot $slotWithContent"
+ }
+ )
+ }
+
+ rule.setContent {
+ Column {
+ repeat(10) { slot ->
+ if (slot == slotWithContent) {
+ ReusableContent(Unit) {
+ movableContext()
+ }
+ } else {
+ BasicText("Slot $slot")
+ }
+ }
+ }
+ }
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(matches(withText("Button in slot 0")))
+ .check(matches(withEffectiveVisibility(VISIBLE)))
+
+ assertEquals(
+ "Binding did not experience the expected event sequence when being " +
+ "initialized in its first position",
+ listOf("inflate", "update"),
+ events
+ )
+
+ events.clear()
+ slotWithContent++
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(matches(withText("Button in slot 1")))
+ .check(matches(withEffectiveVisibility(VISIBLE)))
+
+ assertEquals(
+ "Binding did not experience expected events when moving to its new position " +
+ "when the moved content is updated via composition",
+ listOf("update"),
+ events
+ )
+ }
+
+ @Test
+ fun testViewIsReusedAndReleased_whenDeactivatedOrRemovedAndUpdated() {
+ val events = mutableListOf<String>()
+ var includeContent by mutableStateOf(true)
+ var enableContent by mutableStateOf(true)
+
+ rule.setContent {
+ if (includeContent) {
+ ReusableContentHost(enableContent) {
+ AndroidViewBinding(
+ factory = { inflater, parent, attachToParent ->
+ events += "inflate"
+ SampleButtonLayoutBinding.inflate(inflater, parent, attachToParent)
+ },
+ modifier = Modifier.heightIn(max = 200.dp),
+ onReset = {
+ events += "reset"
+ myButton.text = null
+ },
+ onRelease = { events += "release" },
+ update = {
+ events += "update"
+ myButton.text = "My Button"
+ }
+ )
+ }
+ }
+ }
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(matches(withText("My Button")))
+ .check(matches(withEffectiveVisibility(VISIBLE)))
+
+ assertEquals(
+ "Binding did not experience the expected event sequence when being " +
+ "created for the first time",
+ listOf("inflate", "update"),
+ events
+ )
+
+ events.clear()
+ includeContent = false
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(doesNotExist())
+
+ assertEquals(
+ "Binding should be released when its containing group is removed from composition",
+ listOf("release"),
+ events
+ )
+
+ events.clear()
+ includeContent = true
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(matches(withText("My Button")))
+ .check(matches(withEffectiveVisibility(VISIBLE)))
+
+ assertEquals(
+ "Binding should re-experience its creation lifecycle when its previously removed " +
+ "group is re-added to the composition",
+ listOf("inflate", "update"),
+ events
+ )
+
+ events.clear()
+ enableContent = false
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(doesNotExist())
+
+ assertEquals(
+ "Binding should be reset when its parent ReusableContentHost is deactivated",
+ listOf("reset"),
+ events
+ )
+
+ events.clear()
+ enableContent = true
+
+ onView(withClassName(`is`(ButtonFqClassName)))
+ .check(matches(withText("My Button")))
+ .check(matches(withEffectiveVisibility(VISIBLE)))
+
+ assertEquals(
+ "Binding should be re-awoken when its parent ReusableContentHost becomes active again",
+ listOf("update"),
+ events
+ )
+ }
+
+ @Test
+ fun testFragmentIsReused_whenMoved() {
+ val events = mutableListOf<String>()
+ var slotWithContent by mutableStateOf(0)
+ val movableContext = movableContentOf {
+ AndroidViewBinding(
+ factory = { inflater, parent, attachToParent ->
+ events += "inflate"
+ TestFragmentLayoutBinding.inflate(inflater, parent, attachToParent)
+ },
+ modifier = Modifier.heightIn(max = 200.dp),
+ onReset = { events += "reset" },
+ onRelease = { events += "release" },
+ update = { events += "update" }
+ )
+ }
+
+ rule.setContent {
+ Column {
+ repeat(10) { slot ->
+ if (slot == slotWithContent) {
+ ReusableContent(Unit) {
+ movableContext()
+ }
+ } else {
+ BasicText("Slot $slot")
+ }
+ }
+ }
+ }
+
+ waitForIdleSync()
+
+ assertEquals(
+ "Binding did not experience the expected event sequence when being " +
+ "initialized in its first position",
+ listOf("inflate", "update"),
+ events
+ )
+
+ events.clear()
+ slotWithContent++
+ waitForIdleSync()
+
+ assertEquals(
+ "Binding should not experience any events when moving to its new position",
+ emptyList<String>(),
+ events
+ )
+ }
+
+ @Test
+ fun testFragmentIsReusedAndReleased_whenDeactivatedOrRemoved() {
+ val events = mutableListOf<String>()
+ var includeContent by mutableStateOf(true)
+ var enableContent by mutableStateOf(true)
+
+ rule.setContent {
+ if (includeContent) {
+ ReusableContentHost(enableContent) {
+ AndroidViewBinding(
+ factory = { inflater, parent, attachToParent ->
+ events += "inflate"
+ TestFragmentLayoutBinding.inflate(inflater, parent, attachToParent)
+ },
+ modifier = Modifier.heightIn(max = 200.dp),
+ onReset = { events += "reset" },
+ onRelease = { events += "release" },
+ update = { events += "update" }
+ )
+ }
+ }
+ }
+
+ onView(withId(R.id.fragment_layout)).check(matches(withEffectiveVisibility(VISIBLE)))
+ assertEquals(
+ "Binding did not experience the expected event sequence when being " +
+ "created for the first time",
+ listOf("inflate", "update"),
+ events
+ )
+
+ events.clear()
+ includeContent = false
+
+ onView(withId(R.id.fragment_layout)).check(doesNotExist())
+ assertEquals(
+ "Binding should be released when its containing group is removed from composition",
+ listOf("release"),
+ events
+ )
+
+ events.clear()
+ includeContent = true
+
+ onView(withId(R.id.fragment_layout)).check(matches(withEffectiveVisibility(VISIBLE)))
+ assertEquals(
+ "Binding should re-experience its creation lifecycle when its previously removed " +
+ "group is re-added to the composition",
+ listOf("inflate", "update"),
+ events
+ )
+
+ events.clear()
+ enableContent = false
+
+ onView(withId(R.id.fragment_layout)).check(doesNotExist())
+ assertEquals(
+ "Binding should be reset when its parent ReusableContentHost is deactivated",
+ listOf("reset"),
+ events
+ )
+
+ events.clear()
+ enableContent = true
+
+ onView(withId(R.id.fragment_layout)).check(matches(withEffectiveVisibility(VISIBLE)))
+ assertEquals(
+ "Binding should be re-awoken when its parent ReusableContentHost becomes active again",
+ listOf("update"),
+ events
+ )
+ }
+
+ private fun waitForIdleSync() = rule.runOnIdle { /* Do nothing. */ }
+
+ companion object {
+ private val ButtonFqClassName = Button::class.qualifiedName!!
+ }
+}
\ No newline at end of file
diff --git a/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt b/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt
index 1555523..67baa43 100644
--- a/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt
+++ b/compose/ui/ui-viewbinding/samples/src/main/java/androidx/compose/ui/samples/AndroidViewBindingSample.kt
@@ -19,6 +19,8 @@
import android.graphics.Color
import androidx.annotation.Sampled
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewbinding.samples.databinding.SampleButtonLayoutBinding
import androidx.compose.ui.viewbinding.samples.databinding.SampleLayoutBinding
import androidx.compose.ui.viewinterop.AndroidViewBinding
@@ -30,4 +32,28 @@
AndroidViewBinding(SampleLayoutBinding::inflate) {
second.setBackgroundColor(Color.GRAY)
}
+}
+
+@Sampled
+@Composable
+fun AndroidViewBindingReusableSample() {
+ @Composable
+ fun MyButton(
+ label: String,
+ action: () -> Unit,
+ modifier: Modifier = Modifier
+ ) {
+ AndroidViewBinding(
+ SampleButtonLayoutBinding::inflate,
+ modifier = modifier,
+ onReset = {
+ // Null out the OnClickListener to avoid leaking the `action` lambda.
+ myButton.setOnClickListener(null)
+ },
+ update = {
+ myButton.text = label
+ myButton.setOnClickListener { action() }
+ }
+ )
+ }
}
\ No newline at end of file
diff --git a/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_button_layout.xml b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_button_layout.xml
new file mode 100644
index 0000000..00f137a
--- /dev/null
+++ b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_button_layout.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button android:id="@+id/my_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="My Button" />
+</LinearLayout>
\ No newline at end of file
diff --git a/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml
index 85ba5ee..5a4a9f9 100644
--- a/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml
+++ b/compose/ui/ui-viewbinding/samples/src/main/res/layout/sample_layout.xml
@@ -16,6 +16,7 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/fragment_layout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
diff --git a/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt b/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
index 145df82..1424583 100644
--- a/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
+++ b/compose/ui/ui-viewbinding/src/main/java/androidx/compose/ui/viewinterop/AndroidViewBinding.kt
@@ -16,20 +16,17 @@
package androidx.compose.ui.viewinterop
-import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.ReusableContentHost
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
-import androidx.compose.ui.node.Ref
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.viewbinding.R
import androidx.core.view.forEach
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
@@ -49,19 +46,115 @@
* the block will be reexecuted to set the new properties. Note the block will also be ran once
* right after the [factory] block completes.
*
+ * This overload of [AndroidViewBinding] does not automatically pool or reuse Views and their
+ * bindings. If placed inside of a reusable container (including inside a
+ * [LazyRow][androidx.compose.foundation.lazy.LazyRow] or
+ * [LazyColumn][androidx.compose.foundation.lazy.LazyColumn]), the View instances and their
+ * bindings will always be discarded and recreated if the composition hierarchy containing the
+ * `AndroidViewBinding` changes, even if its group structure did not change and the `View` and its
+ * binding could have conceivably been reused.
+ *
+ * To opt-in for View reuse, call the overload of [AndroidViewBinding] that accepts an `onReset`
+ * callback, and provide a non-null implementation for this callback. Since it is expensive to
+ * discard and recreate View instances, reusing Views can lead to noticeable performance
+ * improvements — especially when building a scrolling list of [AndroidViews][AndroidView]. It is
+ * highly recommended to opt-in to View reuse when possible.
+ *
+ * There is generally no need to opt-in for reuse when using an `AndroidViewBinding` to host a
+ * Fragment, since Fragments have their own view lifecycles and do not usually appear in contexts
+ * where the reuse offered by `AndroidViewBinding` would lead to measurable performance
+ * improvements.
+ *
* @sample androidx.compose.ui.samples.AndroidViewBindingSample
*
* @param factory The block creating the [ViewBinding] to be composed.
* @param modifier The modifier to be applied to the layout.
- * @param update The callback to be invoked after the layout is inflated.
+ * @param update The callback to be invoked after the layout is inflated and upon recomposition to
+ * update the information and state of the binding
*/
@Composable
fun <T : ViewBinding> AndroidViewBinding(
factory: (inflater: LayoutInflater, parent: ViewGroup, attachToParent: Boolean) -> T,
modifier: Modifier = Modifier,
- update: T.() -> Unit = {}
+ update: T.() -> Unit = { }
) {
- val viewBindingRef = remember { Ref<T>() }
+ AndroidViewBinding(
+ factory = factory,
+ modifier = modifier,
+ onReset = null,
+ update = update
+ )
+}
+
+/**
+ * Composes an Android layout resource in the presence of [ViewBinding]. The binding is obtained
+ * from the [factory] block, which will be called exactly once to obtain the [ViewBinding]
+ * to be composed, and it is also guaranteed to be invoked on the UI thread.
+ * Therefore, in addition to creating the [ViewBinding], the block can also be used
+ * to perform one-off initializations and [View] constant properties' setting.
+ * The [update] block can be run multiple times (on the UI thread as well) due to recomposition,
+ * and it is the right place to set [View] properties depending on state. When state changes,
+ * the block will be reexecuted to set the new properties. Note the block will also be ran once
+ * right after the [factory] block completes.
+ *
+ * This overload includes support for View reuse, which behaves in the same way as it does for
+ * [AndroidView]. Namely, Views and their binding instances are only eligible for reuse if a
+ * non-null [onReset] callback is provided. It is expensive to discard and recreate View instances,
+ * so opting-in to View reuse can lead to noticeable performance improvements — especially when
+ * [AndroidViewBinding] is used in a scrolling list. It is highly recommended to specify an
+ * [onReset] implementation and opt-in to View reuse when possible.
+ *
+ * When [onReset] is specified, [View] instances and their bindings may be reused when hosted
+ * inside of a container that supports reusable elements. Reuse occurs when compatible instances
+ * of [AndroidViewBinding] are inserted and removed during recomposition. Two instances of
+ * `AndroidViewBinding` are considered compatible if they are invoked with the same composable
+ * group structure. The most common scenario where this happens is in lazy layout APIs like
+ * `LazyRow` and `LazyColumn`, which can reuse layout nodes (and, in this case, Views and their
+ * bindings as well) between items when scrolling.
+ *
+ * [onReset] is invoked on the UI thread when the View and its binding will be reused, signaling
+ * that the View and binding should be prepared to appear in a new context in the composition
+ * hierarchy. This callback is invoked before [update] and may be used to reset any transient View
+ * state like animations or user input.
+ *
+ * Note that [onReset] may not be immediately followed by a call to [update]. Compose may
+ * temporarily detach the View from the composition hierarchy if it is deactivated but not released
+ * from composition. This can happen if the View appears in a [ReusableContentHost] that is not
+ * currently active or inside of a [movable content][androidx.compose.runtime.movableContentOf]
+ * block that is being moved. If this happens, the View will be removed from its parent, but
+ * retained by Compose so that it may be reused if its content host becomes active again. If the
+ * View never becomes active again and is instead discarded entirely, the [onReset] callback will
+ * be invoked directly from this deactivated state when Compose releases the View and its binding.
+ *
+ * When the View is removed from the composition permanently, [onRelease] will be invoked (also on
+ * the UI thread). Once this callback returns, Compose will never attempt to reuse the previous
+ * View or binding instance regardless of whether an [onReset] implementation was provided. If the
+ * View is needed again in the future, a new instance will be created, with a fresh lifecycle that
+ * begins by calling the [factory].
+ *
+ * @sample androidx.compose.ui.samples.AndroidViewBindingReusableSample
+ *
+ * @param factory The block creating the [ViewBinding] to be composed.
+ * @param modifier The modifier to be applied to the layout.
+ * @param onReset A callback invoked as a signal that the view is about to be attached to the
+ * composition hierarchy in a different context than its original creation. This callback is invoked
+ * before [update] and should prepare the view for general reuse. If `null` or not specified, the
+ * `AndroidViewBinding` instance will not support reuse, and the View and its binding will always be
+ * discarded whenever the AndroidViewBinding is moved or removed from the composition hierarchy.
+ * @param onRelease A callback invoked as a signal that this view and its binding have exited the
+ * composition hierarchy entirely and will not be reused again. Any additional resources used by the
+ * binding should be freed at this time.
+ * @param update The callback to be invoked after the layout is inflated and upon recomposition to
+ * update the information and state of the binding.
+ */
+@Composable
+fun <T : ViewBinding> AndroidViewBinding(
+ factory: (inflater: LayoutInflater, parent: ViewGroup, attachToParent: Boolean) -> T,
+ modifier: Modifier = Modifier,
+ onReset: (T.() -> Unit)? = null,
+ onRelease: T.() -> Unit = { },
+ update: T.() -> Unit = { }
+) {
val localView = LocalView.current
// Find the parent fragment, if one exists. This will let us ensure that
// fragments inflated via a FragmentContainerView are properly nested
@@ -74,62 +167,62 @@
null
}
}
- val fragmentContainerViews = remember { mutableStateListOf<FragmentContainerView>() }
- val viewBlock: (Context) -> View = remember(localView) {
- { context ->
+
+ val localContext = LocalContext.current
+ AndroidView(
+ factory = { context ->
// Inflated fragments are automatically nested properly when
// using the parent fragment's LayoutInflater
val inflater = parentFragment?.layoutInflater ?: LayoutInflater.from(context)
val viewBinding = factory(inflater, FrameLayout(context), false)
- viewBindingRef.value = viewBinding
- // Find all FragmentContainerView instances in the newly inflated layout
- fragmentContainerViews.clear()
- val rootGroup = viewBinding.root as? ViewGroup
- if (rootGroup != null) {
- findFragmentContainerViews(rootGroup, fragmentContainerViews)
+ viewBinding.root.apply {
+ setBinding(viewBinding)
}
- viewBinding.root
- }
- }
- AndroidView(
- factory = viewBlock,
+ },
modifier = modifier,
- update = { viewBindingRef.value?.update() }
- )
+ onReset = onReset?.let { reset -> { view -> view.getBinding<T>().reset() } },
+ onRelease = { view ->
+ view.getBinding<T>().onRelease()
- // Set up a DisposableEffect for each FragmentContainerView that will
- // clean up inflated fragments when the AndroidViewBinding is disposed
- val localContext = LocalContext.current
- fragmentContainerViews.fastForEach { container ->
- DisposableEffect(localContext, container) {
- // Find the right FragmentManager
- val fragmentManager = parentFragment?.childFragmentManager
- ?: (localContext as? FragmentActivity)?.supportFragmentManager
- // Now find the fragment inflated via the FragmentContainerView
- val existingFragment = fragmentManager?.findFragmentById(container.id)
- onDispose {
- if (existingFragment != null && !fragmentManager.isStateSaved) {
- // If the state isn't saved, that means that some state change
- // has removed this Composable from the hierarchy
- fragmentManager.commit {
- remove(existingFragment)
+ (view as? ViewGroup)?.let { rootGroup ->
+ // clean up inflated fragments when the AndroidViewBinding is disposed
+ // Find the right FragmentManager
+ val fragmentManager = parentFragment?.childFragmentManager
+ ?: (localContext as? FragmentActivity)?.supportFragmentManager
+ forEachFragmentContainerView(rootGroup) { container ->
+ // Now find the fragment inflated via the FragmentContainerView
+ val existingFragment = fragmentManager?.findFragmentById(container.id)
+ if (existingFragment != null && !fragmentManager.isStateSaved) {
+ // If the state isn't saved, that means that some state change
+ // has removed this Composable from the hierarchy
+ fragmentManager.commit {
+ remove(existingFragment)
+ }
}
}
}
- }
- }
+ },
+ update = { view -> view.getBinding<T>().update() }
+ )
}
-private fun findFragmentContainerViews(
+private fun <T : ViewBinding> View.setBinding(binding: T) =
+ setTag(R.id.binding_reference, binding)
+
+@Suppress("UNCHECKED_CAST")
+private fun <T : ViewBinding> View.getBinding(): T =
+ getTag(R.id.binding_reference) as T
+
+private fun forEachFragmentContainerView(
viewGroup: ViewGroup,
- list: MutableList<FragmentContainerView>
+ action: (FragmentContainerView) -> Unit
) {
if (viewGroup is FragmentContainerView) {
- list += viewGroup
+ action(viewGroup)
} else {
viewGroup.forEach {
if (it is ViewGroup) {
- findFragmentContainerViews(it, list)
+ forEachFragmentContainerView(it, action)
}
}
}
diff --git a/compose/ui/ui-viewbinding/src/main/res/values/ids.xml b/compose/ui/ui-viewbinding/src/main/res/values/ids.xml
new file mode 100644
index 0000000..110ceb1
--- /dev/null
+++ b/compose/ui/ui-viewbinding/src/main/res/values/ids.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+ <id name="binding_reference"/>
+</resources>
\ No newline at end of file
diff --git a/compose/ui/ui/api/api_lint.ignore b/compose/ui/ui/api/api_lint.ignore
index 4be51cd..b334166 100644
--- a/compose/ui/ui/api/api_lint.ignore
+++ b/compose/ui/ui/api/api_lint.ignore
@@ -1,24 +1,58 @@
// Baseline format: 1.0
+GetterSetterNames: androidx.compose.ui.focus.FocusProperties#getCanFocus():
+ Getter for boolean property `canFocus` is named `getCanFocus` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.focus.FocusState#getHasFocus():
+ Getter for boolean property `hasFocus` is named `getHasFocus` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.layout.BeyondBoundsLayout.BeyondBoundsScope#getHasMoreContent():
+ Getter for boolean property `hasMoreContent` is named `getHasMoreContent` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.AbstractComposeView#getHasComposition():
+ Getter for boolean property `hasComposition` is named `getHasComposition` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.AbstractComposeView#getShouldCreateCompositionOnAttachedToWindow():
+ Getter for boolean property `shouldCreateCompositionOnAttachedToWindow` is named `getShouldCreateCompositionOnAttachedToWindow` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.ComposeView#getShouldCreateCompositionOnAttachedToWindow():
+ Getter for boolean property `shouldCreateCompositionOnAttachedToWindow` is named `getShouldCreateCompositionOnAttachedToWindow` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.compose.ui.platform.ViewRootForTest#getHasPendingMeasureOrLayout():
+ Getter for boolean property `hasPendingMeasureOrLayout` is named `getHasPendingMeasureOrLayout` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field DialogProperties.decorFitsSystemWindows:
+ Invalid name for boolean property `decorFitsSystemWindows`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DialogProperties.dismissOnBackPress:
+ Invalid name for boolean property `dismissOnBackPress`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DialogProperties.dismissOnClickOutside:
+ Invalid name for boolean property `dismissOnClickOutside`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DialogProperties.usePlatformDefaultWidth:
+ Invalid name for boolean property `usePlatformDefaultWidth`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ImageVector.autoMirror:
+ Invalid name for boolean property `autoMirror`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ModifierNodeElement.autoInvalidate:
+ Invalid name for boolean property `autoInvalidate`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputChange.pressed:
+ Invalid name for boolean property `pressed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputChange.previousPressed:
+ Invalid name for boolean property `previousPressed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputFilter.interceptOutOfBoundsChildEvents:
+ Invalid name for boolean property `interceptOutOfBoundsChildEvents`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PointerInputFilter.shareWithSiblings:
+ Invalid name for boolean property `shareWithSiblings`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.clippingEnabled:
+ Invalid name for boolean property `clippingEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.dismissOnBackPress:
+ Invalid name for boolean property `dismissOnBackPress`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.dismissOnClickOutside:
+ Invalid name for boolean property `dismissOnClickOutside`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.excludeFromSystemGesture:
+ Invalid name for boolean property `excludeFromSystemGesture`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.focusable:
+ Invalid name for boolean property `focusable`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopupProperties.usePlatformDefaultWidth:
+ Invalid name for boolean property `usePlatformDefaultWidth`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ScrollAxisRange.reverseScrolling:
+ Invalid name for boolean property `reverseScrolling`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SemanticsNode.mergingEnabled:
+ Invalid name for boolean property `mergingEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+
+
KotlinDefaultParameterOrder: androidx.compose.ui.graphics.vector.ImageVector.Builder#Builder(String, float, float, float, float, long, int, boolean) parameter #0:
Parameter `name` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #0:
- Parameter `id` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #1:
- Parameter `currentTime` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #2:
- Parameter `currentPosition` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #3:
- Parameter `currentPressed` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #4:
- Parameter `pressure` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #5:
- Parameter `previousTime` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #6:
- Parameter `previousPosition` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #7:
- Parameter `previousPressed` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
-KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, float, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #8:
- Parameter `type` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #0:
Parameter `id` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
KotlinDefaultParameterOrder: androidx.compose.ui.input.pointer.PointerInputChange#copy(long, long, long, boolean, long, long, boolean, int, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange>, long) parameter #1:
diff --git a/compose/ui/ui/api/current.ignore b/compose/ui/ui/api/current.ignore
index 2001639..adee0b1 100644
--- a/compose/ui/ui/api/current.ignore
+++ b/compose/ui/ui/api/current.ignore
@@ -1,3 +1,31 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.graphics.vector.VectorConfig#getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.compose.ui.graphics.vector.VectorConfig.getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsConfiguration#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsConfiguration.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#merge(T, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter childValue in androidx.compose.ui.semantics.SemanticsPropertyKey.merge(T parentValue, T childValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.reflect.KProperty<?>, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyKey.setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyReceiver#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyReceiver.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+
+
RemovedClass: androidx.compose.ui.platform.AndroidComposeView_androidKt:
Removed class androidx.compose.ui.platform.AndroidComposeView_androidKt
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 4eb047f..48fd02b 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -107,8 +107,8 @@
ctor public CombinedModifier(androidx.compose.ui.Modifier outer, androidx.compose.ui.Modifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
public final class ComposedModifierKt {
@@ -120,8 +120,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
method public default infix androidx.compose.ui.Modifier then(androidx.compose.ui.Modifier other);
field public static final androidx.compose.ui.Modifier.Companion Companion;
}
@@ -129,15 +129,15 @@
public static final class Modifier.Companion implements androidx.compose.ui.Modifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface Modifier.Element extends androidx.compose.ui.Modifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
public abstract static class Modifier.Node implements androidx.compose.ui.node.DelegatableNode {
@@ -608,7 +608,7 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
- method public default <T> T! getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T? defaultValue);
+ method public default <T> T getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue);
}
@androidx.compose.runtime.Immutable public final class VectorGroup extends androidx.compose.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.compose.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2226,7 +2226,7 @@
public interface ModifierLocalNode extends androidx.compose.ui.modifier.ModifierLocalReadScope androidx.compose.ui.node.DelegatableNode {
method public default <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
method public default androidx.compose.ui.modifier.ModifierLocalMap getProvidedValues();
- method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T? value);
+ method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
}
@@ -2240,13 +2240,13 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface ModifierLocalProvider<T> extends androidx.compose.ui.Modifier.Element {
method public androidx.compose.ui.modifier.ProvidableModifierLocal<T> getKey();
- method public T! getValue();
+ method public T getValue();
property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
- property public abstract T! value;
+ property public abstract T value;
}
public interface ModifierLocalReadScope {
- method public <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+ method public <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
}
@androidx.compose.runtime.Stable public final class ProvidableModifierLocal<T> extends androidx.compose.ui.modifier.ModifierLocal<T> {
@@ -2261,7 +2261,7 @@
}
public final class CompositionLocalConsumerModifierNodeKt {
- method public static <T> T! currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+ method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
}
public interface DelegatableNode {
@@ -2885,13 +2885,13 @@
ctor public SemanticsConfiguration();
method public operator <T> boolean contains(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
method public androidx.compose.ui.semantics.SemanticsConfiguration copy();
- method public operator <T> T! get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
- method public <T> T! getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public operator <T> T get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+ method public <T> T getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public <T> T? getOrElseNullable(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public boolean isClearingSemantics();
method public boolean isMergingSemanticsOfDescendants();
method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
- method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
method public void setClearingSemantics(boolean);
method public void setMergingSemanticsOfDescendants(boolean);
property public final boolean isClearingSemantics;
@@ -3092,14 +3092,14 @@
public final class SemanticsPropertyKey<T> {
ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
method public String getName();
- method public operator T! getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
- method public T? merge(T? parentValue, T? childValue);
- method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+ method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+ method public T? merge(T? parentValue, T childValue);
+ method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value);
property public final String name;
}
public interface SemanticsPropertyReceiver {
- method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
}
}
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index c46de0a..95fddb6 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -107,8 +107,8 @@
ctor public CombinedModifier(androidx.compose.ui.Modifier outer, androidx.compose.ui.Modifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
public final class ComposedModifierKt {
@@ -130,8 +130,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
method public default infix androidx.compose.ui.Modifier then(androidx.compose.ui.Modifier other);
field public static final androidx.compose.ui.Modifier.Companion Companion;
}
@@ -139,15 +139,15 @@
public static final class Modifier.Companion implements androidx.compose.ui.Modifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface Modifier.Element extends androidx.compose.ui.Modifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
public abstract static class Modifier.Node implements androidx.compose.ui.node.DelegatableNode {
@@ -726,7 +726,7 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
- method public default <T> T! getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T? defaultValue);
+ method public default <T> T getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue);
}
@androidx.compose.runtime.Immutable public final class VectorGroup extends androidx.compose.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.compose.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2436,7 +2436,7 @@
public interface ModifierLocalNode extends androidx.compose.ui.modifier.ModifierLocalReadScope androidx.compose.ui.node.DelegatableNode {
method public default <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
method public default androidx.compose.ui.modifier.ModifierLocalMap getProvidedValues();
- method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T? value);
+ method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
}
@@ -2450,9 +2450,9 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface ModifierLocalProvider<T> extends androidx.compose.ui.Modifier.Element {
method public androidx.compose.ui.modifier.ProvidableModifierLocal<T> getKey();
- method public T! getValue();
+ method public T getValue();
property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
- property public abstract T! value;
+ property public abstract T value;
}
public final class ModifierLocalProviderKt {
@@ -2460,7 +2460,7 @@
}
public interface ModifierLocalReadScope {
- method public <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+ method public <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
}
@androidx.compose.runtime.Stable public final class ProvidableModifierLocal<T> extends androidx.compose.ui.modifier.ModifierLocal<T> {
@@ -2475,7 +2475,7 @@
}
public final class CompositionLocalConsumerModifierNodeKt {
- method public static <T> T! currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+ method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
}
public interface DelegatableNode {
@@ -2942,7 +2942,7 @@
@androidx.compose.ui.InternalComposeUiApi public final class WindowRecomposerPolicy {
method public void setFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory);
- method public inline <R> R! withFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory, kotlin.jvm.functions.Function0<? extends R> block);
+ method public inline <R> R withFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory, kotlin.jvm.functions.Function0<? extends R> block);
field public static final androidx.compose.ui.platform.WindowRecomposerPolicy INSTANCE;
}
@@ -3144,13 +3144,13 @@
ctor public SemanticsConfiguration();
method public operator <T> boolean contains(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
method public androidx.compose.ui.semantics.SemanticsConfiguration copy();
- method public operator <T> T! get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
- method public <T> T! getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public operator <T> T get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+ method public <T> T getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public <T> T? getOrElseNullable(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public boolean isClearingSemantics();
method public boolean isMergingSemanticsOfDescendants();
method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
- method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
method public void setClearingSemantics(boolean);
method public void setMergingSemanticsOfDescendants(boolean);
property public final boolean isClearingSemantics;
@@ -3363,14 +3363,14 @@
public final class SemanticsPropertyKey<T> {
ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
method public String getName();
- method public operator T! getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
- method public T? merge(T? parentValue, T? childValue);
- method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+ method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+ method public T? merge(T? parentValue, T childValue);
+ method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value);
property public final String name;
}
public interface SemanticsPropertyReceiver {
- method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
}
}
diff --git a/compose/ui/ui/api/restricted_current.ignore b/compose/ui/ui/api/restricted_current.ignore
index 2001639..adee0b1 100644
--- a/compose/ui/ui/api/restricted_current.ignore
+++ b/compose/ui/ui/api/restricted_current.ignore
@@ -1,3 +1,31 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.CombinedModifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.CombinedModifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Companion#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Companion.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldIn(R, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.Modifier.Element#foldOut(R, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initial in androidx.compose.ui.Modifier.Element.foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation)
+InvalidNullConversion: androidx.compose.ui.graphics.vector.VectorConfig#getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.compose.ui.graphics.vector.VectorConfig.getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsConfiguration#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsConfiguration.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#merge(T, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter childValue in androidx.compose.ui.semantics.SemanticsPropertyKey.merge(T parentValue, T childValue)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyKey#setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.reflect.KProperty<?>, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyKey.setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value)
+InvalidNullConversion: androidx.compose.ui.semantics.SemanticsPropertyReceiver#set(androidx.compose.ui.semantics.SemanticsPropertyKey<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.compose.ui.semantics.SemanticsPropertyReceiver.set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value)
+
+
RemovedClass: androidx.compose.ui.platform.AndroidComposeView_androidKt:
Removed class androidx.compose.ui.platform.AndroidComposeView_androidKt
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 8b45d71..fe0c61d 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -107,8 +107,8 @@
ctor public CombinedModifier(androidx.compose.ui.Modifier outer, androidx.compose.ui.Modifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
public final class ComposedModifierKt {
@@ -120,8 +120,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
method public default infix androidx.compose.ui.Modifier then(androidx.compose.ui.Modifier other);
field public static final androidx.compose.ui.Modifier.Companion Companion;
}
@@ -129,15 +129,15 @@
public static final class Modifier.Companion implements androidx.compose.ui.Modifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface Modifier.Element extends androidx.compose.ui.Modifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
}
public abstract static class Modifier.Node implements androidx.compose.ui.node.DelegatableNode {
@@ -608,7 +608,7 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
- method public default <T> T! getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T? defaultValue);
+ method public default <T> T getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue);
}
@androidx.compose.runtime.Immutable public final class VectorGroup extends androidx.compose.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.compose.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
@@ -2233,7 +2233,7 @@
public interface ModifierLocalNode extends androidx.compose.ui.modifier.ModifierLocalReadScope androidx.compose.ui.node.DelegatableNode {
method public default <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
method public default androidx.compose.ui.modifier.ModifierLocalMap getProvidedValues();
- method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T? value);
+ method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
}
@@ -2247,13 +2247,13 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface ModifierLocalProvider<T> extends androidx.compose.ui.Modifier.Element {
method public androidx.compose.ui.modifier.ProvidableModifierLocal<T> getKey();
- method public T! getValue();
+ method public T getValue();
property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
- property public abstract T! value;
+ property public abstract T value;
}
public interface ModifierLocalReadScope {
- method public <T> T! getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+ method public <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
}
@androidx.compose.runtime.Stable public final class ProvidableModifierLocal<T> extends androidx.compose.ui.modifier.ModifierLocal<T> {
@@ -2309,7 +2309,7 @@
}
public final class CompositionLocalConsumerModifierNodeKt {
- method public static <T> T! currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+ method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
}
public interface DelegatableNode {
@@ -2934,13 +2934,13 @@
ctor public SemanticsConfiguration();
method public operator <T> boolean contains(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
method public androidx.compose.ui.semantics.SemanticsConfiguration copy();
- method public operator <T> T! get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
- method public <T> T! getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public operator <T> T get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+ method public <T> T getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public <T> T? getOrElseNullable(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public boolean isClearingSemantics();
method public boolean isMergingSemanticsOfDescendants();
method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
- method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
method public void setClearingSemantics(boolean);
method public void setMergingSemanticsOfDescendants(boolean);
property public final boolean isClearingSemantics;
@@ -3141,14 +3141,14 @@
public final class SemanticsPropertyKey<T> {
ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
method public String getName();
- method public operator T! getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
- method public T? merge(T? parentValue, T? childValue);
- method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T? value);
+ method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+ method public T? merge(T? parentValue, T childValue);
+ method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value);
property public final String name;
}
public interface SemanticsPropertyReceiver {
- method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
}
}
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
index 5595853..a13aa46 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/HitPathTrackerTest.kt
@@ -3688,7 +3688,8 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
onRequestMeasureParams += layoutNode
if (affectsLookahead) {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
index 18faf11..a1603dd 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessorTest.kt
@@ -3337,7 +3337,8 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
if (affectsLookahead) {
delegate.requestLookaheadRemeasure(layoutNode)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
index 89ff38b..8e4d1a2 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/Helpers.kt
@@ -92,7 +92,8 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
if (affectsLookahead) {
delegate.requestLookaheadRemeasure(layoutNode)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt
index 3e4c2be..eaed850 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/ResizingComposeViewTest.kt
@@ -28,6 +28,8 @@
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.test.TestActivity
import androidx.compose.ui.unit.Constraints
@@ -261,6 +263,60 @@
awaitDrawAndAssertSizes()
}
+ @Test
+ fun whenForceRemeasureCalledAndSizeChanged() {
+ var childHeight by mutableStateOf(10)
+ val parent = RequestLayoutTrackingFrameLayout(rule.activity)
+ var remeasurement: Remeasurement? = null
+ rule.runOnUiThread {
+ parent.addView(composeView, WrapContentLayoutParams)
+ rule.activity.setContentView(parent, WrapContentLayoutParams)
+ composeView.setContent {
+ ResizingChild(
+ layoutHeight = { childHeight },
+ modifier = RemeasurementModifierElement { remeasurement = it }
+ )
+ }
+ }
+
+ awaitDrawAndAssertSizes()
+ rule.runOnUiThread {
+ parent.requestLayoutCalled = false
+ drawLatch = CountDownLatch(1)
+
+ childHeight = 20
+ remeasurement!!.forceRemeasure()
+ }
+
+ awaitDrawAndAssertSizes()
+ assertThat(parent.requestLayoutCalled).isTrue()
+ }
+
+ @Test
+ fun noRequestLayoutWhenForceRemeasureCalled() {
+ val parent = RequestLayoutTrackingFrameLayout(rule.activity)
+ var remeasurement: Remeasurement? = null
+ rule.runOnUiThread {
+ parent.addView(composeView, WrapContentLayoutParams)
+ rule.activity.setContentView(parent, WrapContentLayoutParams)
+ composeView.setContent {
+ ResizingChild(
+ layoutHeight = { 10 },
+ modifier = RemeasurementModifierElement { remeasurement = it }
+ )
+ }
+ }
+
+ awaitDrawAndAssertSizes()
+ rule.runOnUiThread {
+ parent.requestLayoutCalled = false
+
+ remeasurement!!.forceRemeasure()
+
+ assertThat(parent.requestLayoutCalled).isFalse()
+ }
+ }
+
private fun awaitDrawAndAssertSizes() {
Assert.assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
// size assertion is done inside Modifier.drawBehind() which calls countDown() on the latch
@@ -270,10 +326,11 @@
private fun ResizingChild(
layoutHeight: () -> Int,
viewHeight: () -> Int = layoutHeight,
+ modifier: Modifier = Modifier
) {
Layout(
{},
- Modifier.drawBehind {
+ modifier.drawBehind {
val expectedLayoutHeight = Snapshot.withoutReadObservation { layoutHeight() }
assertWithMessage("Layout size is wrong")
.that(size.height.roundToInt()).isEqualTo(expectedLayoutHeight)
@@ -332,3 +389,28 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
+
+private class RemeasurementModifierElement(
+ private val onRemeasurementAvailable: (Remeasurement) -> Unit
+) : ModifierNodeElement<RemeasurementModifierNode>() {
+ override fun create() = RemeasurementModifierNode().also {
+ onRemeasurementAvailable(it)
+ }
+ override fun update(node: RemeasurementModifierNode) = node.also {
+ onRemeasurementAvailable(it)
+ }
+ override fun hashCode(): Int = 242
+ override fun equals(other: Any?) = other === this
+}
+
+private class RemeasurementModifierNode : Modifier.Node(), LayoutModifierNode {
+ override fun MeasureScope.measure(
+ measurable: Measurable,
+ constraints: Constraints
+ ): MeasureResult {
+ val placeable = measurable.measure(constraints)
+ return layout(placeable.width, placeable.height) {
+ placeable.place(0, 0)
+ }
+ }
+}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 5c19f10..3b68870 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -841,13 +841,18 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
if (affectsLookahead) {
- if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest)) {
+ if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest) &&
+ scheduleMeasureAndLayout
+ ) {
scheduleMeasureAndLayout(layoutNode)
}
- } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest)) {
+ } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest) &&
+ scheduleMeasureAndLayout
+ ) {
scheduleMeasureAndLayout(layoutNode)
}
}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
index 57e248f..e47c66b 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/viewinterop/AndroidView.android.kt
@@ -183,12 +183,12 @@
* @sample androidx.compose.ui.samples.AndroidViewWithReleaseSample
*
* @param factory The block creating the [View] to be composed.
+ * @param modifier The modifier to be applied to the layout.
* @param onReset A callback invoked as a signal that the view is about to be attached to the
* composition hierarchy in a different context than its original creation. This callback is invoked
* before [update] and should prepare the view for general reuse. If `null` or not specified, the
* `AndroidView` instance will not support reuse, and the View instance will always be discarded
* whenever the AndroidView is moved or removed from the composition hierarchy.
- * @param modifier The modifier to be applied to the layout.
* @param onRelease A callback invoked as a signal that this view instance has exited the
* composition hierarchy entirely and will not be reused again. Any additional resources used by the
* View should be freed at this time.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
index 25e9c36..d3dced6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/TwoDimensionalFocusSearch.kt
@@ -186,6 +186,9 @@
accessibleChildren: MutableVector<FocusTargetModifierNode>
) {
visitChildren(Nodes.FocusTarget) {
+ // TODO(b/278765590): Find the root issue why visitChildren returns unattached nodes.
+ if (!it.isAttached) return@visitChildren
+
if (it.fetchFocusProperties().canFocus) {
accessibleChildren.add(it)
} else {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
index f19d852..aff7b04 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
@@ -949,10 +949,17 @@
/**
* Used to request a new measurement + layout pass from the owner.
*/
- internal fun requestRemeasure(forceRequest: Boolean = false) {
+ internal fun requestRemeasure(
+ forceRequest: Boolean = false,
+ scheduleMeasureAndLayout: Boolean = true
+ ) {
if (!ignoreRemeasureRequests && !isVirtual) {
val owner = owner ?: return
- owner.onRequestMeasure(this, forceRequest = forceRequest)
+ owner.onRequestMeasure(
+ layoutNode = this,
+ forceRequest = forceRequest,
+ scheduleMeasureAndLayout = scheduleMeasureAndLayout
+ )
measurePassDelegate.invalidateIntrinsicsParent(forceRequest)
}
}
@@ -961,14 +968,22 @@
* Used to request a new lookahead measurement, lookahead layout, and subsequently
* measure and layout from the owner.
*/
- internal fun requestLookaheadRemeasure(forceRequest: Boolean = false) {
+ internal fun requestLookaheadRemeasure(
+ forceRequest: Boolean = false,
+ scheduleMeasureAndLayout: Boolean = true
+ ) {
check(lookaheadRoot != null) {
"Lookahead measure cannot be requested on a node that is not a part of the" +
"LookaheadLayout"
}
val owner = owner ?: return
if (!ignoreRemeasureRequests && !isVirtual) {
- owner.onRequestMeasure(this, affectsLookahead = true, forceRequest = forceRequest)
+ owner.onRequestMeasure(
+ layoutNode = this,
+ affectsLookahead = true,
+ forceRequest = forceRequest,
+ scheduleMeasureAndLayout = scheduleMeasureAndLayout
+ )
lookaheadPassDelegate!!.invalidateIntrinsicsParent(forceRequest)
}
}
@@ -1156,10 +1171,11 @@
layoutDelegate.markLookaheadMeasurePending()
override fun forceRemeasure() {
+ // we do not schedule measure and layout as we are going to call it manually right after
if (lookaheadRoot != null) {
- requestLookaheadRemeasure()
+ requestLookaheadRemeasure(scheduleMeasureAndLayout = false)
} else {
- requestRemeasure()
+ requestRemeasure(scheduleMeasureAndLayout = false)
}
val lastConstraints = layoutDelegate.lastConstraints
if (lastConstraints != null) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
index 41cdde0..426e1f7 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/Owner.kt
@@ -154,7 +154,8 @@
fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean = false,
- forceRequest: Boolean = false
+ forceRequest: Boolean = false,
+ scheduleMeasureAndLayout: Boolean = true
)
/**
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
index e649130..66310c1 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
@@ -329,13 +329,18 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
if (affectsLookahead) {
- if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest)) {
+ if (measureAndLayoutDelegate.requestLookaheadRemeasure(layoutNode, forceRequest) &&
+ scheduleMeasureAndLayout
+ ) {
requestLayout()
}
- } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest)) {
+ } else if (measureAndLayoutDelegate.requestRemeasure(layoutNode, forceRequest) &&
+ scheduleMeasureAndLayout
+ ) {
requestLayout()
}
}
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
index 132252b..5c31d51 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
@@ -2558,7 +2558,8 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
onRequestMeasureParams += layoutNode
if (affectsLookahead) {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
index d2c911d..62a2b15 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
@@ -317,7 +317,8 @@
override fun onRequestMeasure(
layoutNode: LayoutNode,
affectsLookahead: Boolean,
- forceRequest: Boolean
+ forceRequest: Boolean,
+ scheduleMeasureAndLayout: Boolean
) {
}
diff --git a/constraintlayout/constraintlayout-compose/api/api_lint.ignore b/constraintlayout/constraintlayout-compose/api/api_lint.ignore
index 33c2cfc..71cc70d 100644
--- a/constraintlayout/constraintlayout-compose/api/api_lint.ignore
+++ b/constraintlayout/constraintlayout-compose/api/api_lint.ignore
@@ -5,6 +5,14 @@
Parameter type is concrete collection (`java.util.HashMap`); must be higher-level interface
+GetterSetterNames: field DebugFlags.showBounds:
+ Invalid name for boolean property `showBounds`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DebugFlags.showKeyPositions:
+ Invalid name for boolean property `showKeyPositions`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field DebugFlags.showPaths:
+ Invalid name for boolean property `showPaths`. Should start with one of `has`, `can`, `should`, `is`.
+
+
KotlinDefaultParameterOrder: androidx.constraintlayout.compose.MotionLayoutKt#MotionLayout(androidx.constraintlayout.compose.ConstraintSet, androidx.constraintlayout.compose.ConstraintSet, androidx.compose.ui.Modifier, androidx.constraintlayout.compose.Transition, float, int, androidx.constraintlayout.compose.LayoutInformationReceiver, int, kotlin.jvm.functions.Function1<? super androidx.constraintlayout.compose.MotionLayoutScope,kotlin.Unit>) parameter #2:
Parameter `modifier` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
KotlinDefaultParameterOrder: androidx.constraintlayout.compose.MotionLayoutKt#MotionLayout(androidx.constraintlayout.compose.ConstraintSet, androidx.constraintlayout.compose.ConstraintSet, androidx.compose.ui.Modifier, androidx.constraintlayout.compose.Transition, float, int, androidx.constraintlayout.compose.LayoutInformationReceiver, int, kotlin.jvm.functions.Function1<? super androidx.constraintlayout.compose.MotionLayoutScope,kotlin.Unit>) parameter #3:
diff --git a/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt b/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
index 92a3feb..49794f2 100644
--- a/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
+++ b/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
@@ -23,12 +23,12 @@
}
@androidx.constraintlayout.compose.ExperimentalMotionApi public abstract class BaseKeyFrameScope {
- method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E? initialValue, optional String? nameOverride);
- method protected final <T> kotlin.properties.ObservableProperty<T> addOnPropertyChange(T? initialValue, optional String? nameOverride);
+ method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E initialValue, optional String? nameOverride);
+ method protected final <T> kotlin.properties.ObservableProperty<T> addOnPropertyChange(T initialValue, optional String? nameOverride);
}
@androidx.constraintlayout.compose.ExperimentalMotionApi public class BaseKeyFramesScope {
- method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E? initialValue, optional String? nameOverride);
+ method protected final <E extends androidx.constraintlayout.compose.NamedPropertyOrValue> kotlin.properties.ObservableProperty<E> addNameOnPropertyChange(E initialValue, optional String? nameOverride);
method public final androidx.constraintlayout.compose.Easing getEasing();
method protected final androidx.constraintlayout.core.parser.CLArray getFramesContainer();
method public final void setEasing(androidx.constraintlayout.compose.Easing);
diff --git a/constraintlayout/constraintlayout/api/current.txt b/constraintlayout/constraintlayout/api/current.txt
index 6e30c9f..469ddb0 100644
--- a/constraintlayout/constraintlayout/api/current.txt
+++ b/constraintlayout/constraintlayout/api/current.txt
@@ -120,20 +120,6 @@
field protected float mComputedMinY;
}
- public class LogJson extends androidx.constraintlayout.widget.ConstraintHelper {
- ctor public LogJson(android.content.Context);
- ctor public LogJson(android.content.Context, android.util.AttributeSet?);
- ctor public LogJson(android.content.Context, android.util.AttributeSet?, int);
- method public void periodicStart();
- method public void periodicStop();
- method public void setDelay(int);
- method public void writeLog();
- field public static final int LOG_API = 4; // 0x4
- field public static final int LOG_DELAYED = 2; // 0x2
- field public static final int LOG_LAYOUT = 3; // 0x3
- field public static final int LOG_PERIODIC = 1; // 0x1
- }
-
public class MotionEffect extends androidx.constraintlayout.motion.widget.MotionHelper {
ctor public MotionEffect(android.content.Context!);
ctor public MotionEffect(android.content.Context!, android.util.AttributeSet!);
diff --git a/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt b/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt
index 6e30c9f..469ddb0 100644
--- a/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt
+++ b/constraintlayout/constraintlayout/api/public_plus_experimental_current.txt
@@ -120,20 +120,6 @@
field protected float mComputedMinY;
}
- public class LogJson extends androidx.constraintlayout.widget.ConstraintHelper {
- ctor public LogJson(android.content.Context);
- ctor public LogJson(android.content.Context, android.util.AttributeSet?);
- ctor public LogJson(android.content.Context, android.util.AttributeSet?, int);
- method public void periodicStart();
- method public void periodicStop();
- method public void setDelay(int);
- method public void writeLog();
- field public static final int LOG_API = 4; // 0x4
- field public static final int LOG_DELAYED = 2; // 0x2
- field public static final int LOG_LAYOUT = 3; // 0x3
- field public static final int LOG_PERIODIC = 1; // 0x1
- }
-
public class MotionEffect extends androidx.constraintlayout.motion.widget.MotionHelper {
ctor public MotionEffect(android.content.Context!);
ctor public MotionEffect(android.content.Context!, android.util.AttributeSet!);
diff --git a/constraintlayout/constraintlayout/api/restricted_current.txt b/constraintlayout/constraintlayout/api/restricted_current.txt
index 6e30c9f..469ddb0 100644
--- a/constraintlayout/constraintlayout/api/restricted_current.txt
+++ b/constraintlayout/constraintlayout/api/restricted_current.txt
@@ -120,20 +120,6 @@
field protected float mComputedMinY;
}
- public class LogJson extends androidx.constraintlayout.widget.ConstraintHelper {
- ctor public LogJson(android.content.Context);
- ctor public LogJson(android.content.Context, android.util.AttributeSet?);
- ctor public LogJson(android.content.Context, android.util.AttributeSet?, int);
- method public void periodicStart();
- method public void periodicStop();
- method public void setDelay(int);
- method public void writeLog();
- field public static final int LOG_API = 4; // 0x4
- field public static final int LOG_DELAYED = 2; // 0x2
- field public static final int LOG_LAYOUT = 3; // 0x3
- field public static final int LOG_PERIODIC = 1; // 0x1
- }
-
public class MotionEffect extends androidx.constraintlayout.motion.widget.MotionHelper {
ctor public MotionEffect(android.content.Context!);
ctor public MotionEffect(android.content.Context!, android.util.AttributeSet!);
diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/LogJson.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/LogJson.java
deleted file mode 100644
index 6b1c9db..0000000
--- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/helper/widget/LogJson.java
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.constraintlayout.helper.widget;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
-import static androidx.constraintlayout.widget.ConstraintSet.Layout.UNSET_GONE_MARGIN;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.Environment;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-import androidx.annotation.RequiresApi;
-import androidx.constraintlayout.motion.widget.Debug;
-import androidx.constraintlayout.widget.ConstraintAttribute;
-import androidx.constraintlayout.widget.ConstraintHelper;
-import androidx.constraintlayout.widget.ConstraintLayout;
-import androidx.constraintlayout.widget.ConstraintSet;
-import androidx.constraintlayout.widget.R;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * This is a class is a debugging/logging utility to write out the constraints in JSON
- * This is used for debugging purposes
- * <ul>
- * <li>logJsonTo - defines the output log console or "fileName"</li>
- * <li>logJsonMode - mode one of:
- * <b>periodic</b>, <b>delayed</b>, <b>layout</b> or <b>api</b></li>
- * <li>logJsonDelay - the duration of the delay or the delay between repeated logs</li>
- * </ul>
- * logJsonTo supports:
- * <ul>
- * <li>log - logs using log.v("JSON5", ...)</li>
- * <li>console - logs using System.out.println(...)</li>
- * <li>[fileName] - will write to /storage/emulated/0/Download/[fileName].json5</li>
- * </ul>
- * logJsonMode modes are:
- * <ul>
- * <li>periodic - after window is attached will log every delay ms</li>
- * <li>delayed - log once after delay ms</li>
- * <li>layout - log every time there is a layout call</li>
- * <li>api - do not automatically log developer will call writeLog</li>
- * </ul>
- *
- * The defaults are:
- * <ul>
- * <li>logJsonTo="log"</li>
- * <li>logJsonMode="delayed"</li>
- * <li>logJsonDelay="1000"</li>
- * </ul>
- * Usage:
- * <p></p>
- * <pre>
- * {@code
- * <androidx.constraintlayout.helper.widget.LogJson
- * android:layout_width="0dp"
- * android:layout_height="0dp"
- * android:visibility="gone"
- * app:logJsonTo="log"
- * app:logJsonMode="delayed"
- * app:logJsonDelay="1000"
- * />
- * }
- * </pre>
- * </p>
- */
-public class LogJson extends ConstraintHelper {
- private static final String TAG = "JSON5";
- private int mDelay = 1000;
- private int mMode = LOG_DELAYED;
- private String mLogToFile = null;
- private boolean mLogConsole = true;
-
- public static final int LOG_PERIODIC = 1;
- public static final int LOG_DELAYED = 2;
- public static final int LOG_LAYOUT = 3;
- public static final int LOG_API = 4;
- private boolean mPeriodic = false;
-
- public LogJson(@androidx.annotation.NonNull Context context) {
- super(context);
- }
-
- public LogJson(@androidx.annotation.NonNull Context context,
- @androidx.annotation.Nullable AttributeSet attrs) {
- super(context, attrs);
- initLogJson(attrs);
-
- }
-
- public LogJson(@androidx.annotation.NonNull Context context,
- @androidx.annotation.Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initLogJson(attrs);
- }
-
- private void initLogJson(AttributeSet attrs) {
-
- if (attrs != null) {
- TypedArray a = getContext().obtainStyledAttributes(attrs,
- R.styleable.LogJson);
- final int count = a.getIndexCount();
- for (int i = 0; i < count; i++) {
- int attr = a.getIndex(i);
- if (attr == R.styleable.LogJson_logJsonDelay) {
- mDelay = a.getInt(attr, mDelay);
- } else if (attr == R.styleable.LogJson_logJsonMode) {
- mMode = a.getInt(attr, mMode);
- } else if (attr == R.styleable.LogJson_logJsonTo) {
- TypedValue v = a.peekValue(attr);
- if (v.type == TypedValue.TYPE_STRING) {
- mLogToFile = a.getString(attr);
- } else {
- int value = a.getInt(attr, 0);
- mLogConsole = value == 2;
- }
- }
- }
- a.recycle();
- }
- setVisibility(GONE);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- switch (mMode) {
- case LOG_PERIODIC:
- mPeriodic = true;
- this.postDelayed(this::periodic, mDelay);
- break;
- case LOG_DELAYED:
- this.postDelayed(this::writeLog, mDelay);
- break;
- case LOG_LAYOUT:
- ConstraintLayout cl = (ConstraintLayout) getParent();
- cl.addOnLayoutChangeListener((v, a, b, c, d, e, f, g, h) -> logOnLayout());
- }
- }
-
- private void logOnLayout() {
- if (mMode == LOG_LAYOUT) {
- writeLog();
- }
- }
-
- /**
- * Set the duration of periodic logging of constraints
- *
- * @param duration the time in ms between writing files
- */
- public void setDelay(int duration) {
- mDelay = duration;
- }
-
- /**
- * Start periodic sampling
- */
- public void periodicStart() {
- if (mPeriodic) {
- return;
- }
- mPeriodic = true;
- this.postDelayed(this::periodic, mDelay);
- }
-
- /**
- * Stop periodic sampling
- */
- public void periodicStop() {
- mPeriodic = false;
- }
-
- private void periodic() {
- if (mPeriodic) {
- writeLog();
- this.postDelayed(this::periodic, mDelay);
- }
- }
-
- /**
- * This writes a JSON5 representation of the constraintSet
- */
- public void writeLog() {
- String str = asString((ConstraintLayout) this.getParent());
- if (mLogToFile == null) {
- if (mLogConsole) {
- System.out.println(str);
- } else {
- logBigString(str);
- }
- } else {
- String name = toFile(str, mLogToFile);
- Log.v("JSON", "\"" + name + "\" written!");
- }
- }
-
- /**
- * This writes the JSON5 description of the constraintLayout to a file named fileName.json5
- * in the download directory which can be pulled with:
- * "adb pull "/storage/emulated/0/Download/" ."
- *
- * @param str String to write as a file
- * @param fileName file name
- * @return full path name of file
- */
- private static String toFile(String str, String fileName) {
- FileOutputStream outputStream;
- if (!fileName.endsWith(".json5")) {
- fileName += ".json5";
- }
- try {
- File down =
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
- File file = new File(down, fileName);
- outputStream = new FileOutputStream(file);
- outputStream.write(str.getBytes());
- outputStream.close();
- return file.getCanonicalPath();
- } catch (IOException e) {
- return e.toString();
- }
- }
-
- @SuppressLint("LogConditional")
- private void logBigString(String str) {
- int len = str.length();
- for (int i = 0; i < len; i++) {
- int k = str.indexOf("\n", i);
- if (k == -1) {
- Log.v(TAG, str.substring(i));
- break;
- }
- Log.v(TAG, str.substring(i, k));
- i = k;
- }
- }
-
- /**
- * Get a JSON5 String that represents the Constraints in a running ConstraintLayout
- *
- * @param constraintLayout its constraints are converted to a string
- * @return JSON5 string
- */
- private static String asString(ConstraintLayout constraintLayout) {
- JsonWriter c = new JsonWriter();
- return c.constraintLayoutToJson(constraintLayout);
- }
-
- // ================================== JSON writer==============================================
-
- private static class JsonWriter {
- public static final int UNSET = ConstraintLayout.LayoutParams.UNSET;
- ConstraintSet mSet;
- Writer mWriter;
- Context mContext;
- int mUnknownCount = 0;
- final String mLEFT = "left";
- final String mRIGHT = "right";
- final String mBASELINE = "baseline";
- final String mBOTTOM = "bottom";
- final String mTOP = "top";
- final String mSTART = "start";
- final String mEND = "end";
- private static final String INDENT = " ";
- private static final String SMALL_INDENT = " ";
- HashMap<Integer, String> mIdMap = new HashMap<>();
- private static final String LOG_JSON = LogJson.class.getSimpleName();
- private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
- HashMap<Integer, String> mNames = new HashMap<>();
-
- private static int generateViewId() {
- final int max_id = 0x00FFFFFF;
- for (;;) {
- final int result = sNextGeneratedId.get();
- int newValue = result + 1;
- if (newValue > max_id) {
- newValue = 1;
- }
- if (sNextGeneratedId.compareAndSet(result, newValue)) {
- return result;
- }
- }
- }
-
- @RequiresApi(17)
- private static class JellyBean {
- static int generateViewId() {
- return View.generateViewId();
- }
- }
-
- String constraintLayoutToJson(ConstraintLayout constraintLayout) {
- StringWriter writer = new StringWriter();
-
- int count = constraintLayout.getChildCount();
- for (int i = 0; i < count; i++) {
- View v = constraintLayout.getChildAt(i);
- String name = v.getClass().getSimpleName();
- int id = v.getId();
- if (id == -1) {
- if (android.os.Build.VERSION.SDK_INT
- >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
- id = JellyBean.generateViewId();
- } else {
- id = generateViewId();
- }
- v.setId(id);
- if (!LOG_JSON.equals(name)) {
- name = "noid_" + name;
- }
- mNames.put(id, name);
- } else if (LOG_JSON.equals(name)) {
- mNames.put(id, name);
- }
- }
- writer.append("{\n");
-
- writeWidgets(writer, constraintLayout);
- writer.append(" ConstraintSet:{\n");
- ConstraintSet set = new ConstraintSet();
- set.clone(constraintLayout);
- String name =
- (constraintLayout.getId() == -1) ? "cset" : Debug.getName(constraintLayout);
- try {
- writer.append(name + ":");
- setup(writer, set, constraintLayout);
- writeLayout();
- writer.append("\n");
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- writer.append(" }\n");
- writer.append("}\n");
- return writer.toString();
- }
-
- private void writeWidgets(StringWriter writer, ConstraintLayout constraintLayout) {
- writer.append("Widgets:{\n");
- int count = constraintLayout.getChildCount();
-
- for (int i = -1; i < count; i++) {
- View v = (i == -1) ? constraintLayout : constraintLayout.getChildAt(i);
- int id = v.getId();
- if (LOG_JSON.equals(v.getClass().getSimpleName())) {
- continue;
- }
- String name = mNames.containsKey(id) ? mNames.get(id)
- : ((i == -1) ? "parent" : Debug.getName(v));
- String cname = v.getClass().getSimpleName();
- String bounds = ", bounds: [" + v.getLeft() + ", " + v.getTop()
- + ", " + v.getRight() + ", " + v.getBottom() + "]},\n";
- writer.append(" " + name + ": { ");
- if (i == -1) {
- writer.append("type: '" + v.getClass().getSimpleName() + "' , ");
-
- try {
- ViewGroup.LayoutParams p = (ViewGroup.LayoutParams) v.getLayoutParams();
- String wrap = "'WRAP_CONTENT'";
- String match = "'MATCH_PARENT'";
- String w = p.width == MATCH_PARENT ? match :
- (p.width == WRAP_CONTENT) ? wrap : p.width + "";
- writer.append("width: " + w + ", ");
- String h = p.height == MATCH_PARENT ? match :
- (p.height == WRAP_CONTENT) ? wrap : p.height + "";
- writer.append("height: ").append(h);
- } catch (Exception e) {
- }
- } else if (cname.contains("Text")) {
- if (v instanceof TextView) {
- writer.append("type: 'Text', label: '"
- + escape(((TextView) v).getText().toString()) + "'");
- } else {
- writer.append("type: 'Text' },\n");
- }
- } else if (cname.contains("Button")) {
- if (v instanceof Button) {
- writer.append("type: 'Button', label: '" + ((Button) v).getText() + "'");
- } else
- writer.append("type: 'Button'");
- } else if (cname.contains("Image")) {
- writer.append("type: 'Image'");
- } else if (cname.contains("View")) {
- writer.append("type: 'Box'");
- } else {
- writer.append("type: '" + v.getClass().getSimpleName() + "'");
- }
- writer.append(bounds);
- }
- writer.append("},\n");
- }
-
- private static String escape(String str) {
- return str.replaceAll("'", "\\'");
- }
-
- JsonWriter() {
- }
-
- void setup(Writer writer,
- ConstraintSet set,
- ConstraintLayout layout) throws IOException {
- this.mWriter = writer;
- this.mContext = layout.getContext();
- this.mSet = set;
- set.getConstraint(2);
- }
-
- private int[] getIDs() {
- return mSet.getKnownIds();
- }
-
- private ConstraintSet.Constraint getConstraint(int id) {
- return mSet.getConstraint(id);
- }
-
- private void writeLayout() throws IOException {
- mWriter.write("{\n");
- for (Integer id : getIDs()) {
- ConstraintSet.Constraint c = getConstraint(id);
- String idName = getSimpleName(id);
- if (LOG_JSON.equals(idName)) { // skip LogJson it is for used to log
- continue;
- }
- mWriter.write(SMALL_INDENT + idName + ":{\n");
- ConstraintSet.Layout l = c.layout;
- if (l.mReferenceIds != null) {
- StringBuilder ref =
- new StringBuilder("type: '_" + idName + "_' , contains: [");
- for (int r = 0; r < l.mReferenceIds.length; r++) {
- int rid = l.mReferenceIds[r];
- ref.append((r == 0) ? "" : ", ").append(getName(rid));
- }
- mWriter.write(ref + "]\n");
- }
- if (l.mReferenceIdString != null) {
- StringBuilder ref =
- new StringBuilder(SMALL_INDENT + "type: '???' , contains: [");
- String[] rids = l.mReferenceIdString.split(",");
- for (int r = 0; r < rids.length; r++) {
- String rid = rids[r];
- ref.append((r == 0) ? "" : ", ").append("`").append(rid).append("`");
- }
- mWriter.write(ref + "]\n");
- }
- writeDimension("height", l.mHeight, l.heightDefault, l.heightPercent,
- l.heightMin, l.heightMax, l.constrainedHeight);
- writeDimension("width", l.mWidth, l.widthDefault, l.widthPercent,
- l.widthMin, l.widthMax, l.constrainedWidth);
-
- writeConstraint(mLEFT, l.leftToLeft, mLEFT, l.leftMargin, l.goneLeftMargin);
- writeConstraint(mLEFT, l.leftToRight, mRIGHT, l.leftMargin, l.goneLeftMargin);
- writeConstraint(mRIGHT, l.rightToLeft, mLEFT, l.rightMargin, l.goneRightMargin);
- writeConstraint(mRIGHT, l.rightToRight, mRIGHT, l.rightMargin, l.goneRightMargin);
- writeConstraint(mBASELINE, l.baselineToBaseline, mBASELINE, UNSET,
- l.goneBaselineMargin);
- writeConstraint(mBASELINE, l.baselineToTop, mTOP, UNSET, l.goneBaselineMargin);
- writeConstraint(mBASELINE, l.baselineToBottom,
- mBOTTOM, UNSET, l.goneBaselineMargin);
-
- writeConstraint(mTOP, l.topToBottom, mBOTTOM, l.topMargin, l.goneTopMargin);
- writeConstraint(mTOP, l.topToTop, mTOP, l.topMargin, l.goneTopMargin);
- writeConstraint(mBOTTOM, l.bottomToBottom, mBOTTOM, l.bottomMargin,
- l.goneBottomMargin);
- writeConstraint(mBOTTOM, l.bottomToTop, mTOP, l.bottomMargin, l.goneBottomMargin);
- writeConstraint(mSTART, l.startToStart, mSTART, l.startMargin, l.goneStartMargin);
- writeConstraint(mSTART, l.startToEnd, mEND, l.startMargin, l.goneStartMargin);
- writeConstraint(mEND, l.endToStart, mSTART, l.endMargin, l.goneEndMargin);
- writeConstraint(mEND, l.endToEnd, mEND, l.endMargin, l.goneEndMargin);
-
- writeVariable("horizontalBias", l.horizontalBias, 0.5f);
- writeVariable("verticalBias", l.verticalBias, 0.5f);
-
- writeCircle(l.circleConstraint, l.circleAngle, l.circleRadius);
-
- writeGuideline(l.orientation, l.guideBegin, l.guideEnd, l.guidePercent);
- writeVariable("dimensionRatio", l.dimensionRatio);
- writeVariable("barrierMargin", l.mBarrierMargin);
- writeVariable("type", l.mHelperType);
- writeVariable("ReferenceId", l.mReferenceIdString);
- writeVariable("mBarrierAllowsGoneWidgets",
- l.mBarrierAllowsGoneWidgets, true);
- writeVariable("WrapBehavior", l.mWrapBehavior);
-
- writeVariable("verticalWeight", l.verticalWeight);
- writeVariable("horizontalWeight", l.horizontalWeight);
- writeVariable("horizontalChainStyle", l.horizontalChainStyle);
- writeVariable("verticalChainStyle", l.verticalChainStyle);
- writeVariable("barrierDirection", l.mBarrierDirection);
- if (l.mReferenceIds != null) {
- writeVariable("ReferenceIds", l.mReferenceIds);
- }
- writeTransform(c.transform);
- writeCustom(c.mCustomConstraints);
-
- mWriter.write(" },\n");
- }
- mWriter.write("},\n");
- }
-
- private void writeTransform(ConstraintSet.Transform transform) throws IOException {
- if (transform.applyElevation) {
- writeVariable("elevation", transform.elevation);
- }
- writeVariable("rotationX", transform.rotationX, 0);
- writeVariable("rotationY", transform.rotationY, 0);
- writeVariable("rotationZ", transform.rotation, 0);
- writeVariable("scaleX", transform.scaleX, 1);
- writeVariable("scaleY", transform.scaleY, 1);
- writeVariable("translationX", transform.translationX, 0);
- writeVariable("translationY", transform.translationY, 0);
- writeVariable("translationZ", transform.translationZ, 0);
- }
-
- private void writeCustom(HashMap<String, ConstraintAttribute> cset) throws IOException {
- if (cset != null && cset.size() > 0) {
- mWriter.write(INDENT + "custom: {\n");
- for (String s : cset.keySet()) {
- ConstraintAttribute attr = cset.get(s);
- if (attr == null) {
- continue;
- }
- String custom = INDENT + SMALL_INDENT + attr.getName() + ": ";
- switch (attr.getType()) {
- case INT_TYPE:
- custom += attr.getIntegerValue();
- break;
- case COLOR_TYPE:
- custom += colorString(attr.getColorValue());
- break;
- case FLOAT_TYPE:
- custom += attr.getFloatValue();
- break;
- case STRING_TYPE:
- custom += "'" + attr.getStringValue() + "'";
- break;
- case DIMENSION_TYPE:
- custom = custom + attr.getFloatValue();
- break;
- case REFERENCE_TYPE:
- case COLOR_DRAWABLE_TYPE:
- case BOOLEAN_TYPE:
- custom = null;
- }
- if (custom != null) {
- mWriter.write(custom + ",\n");
- }
- }
- mWriter.write(SMALL_INDENT + " } \n");
- }
- }
-
- private static String colorString(int v) {
- String str = "00000000" + Integer.toHexString(v);
- return "#" + str.substring(str.length() - 8);
- }
-
- private void writeGuideline(int orientation,
- int guideBegin,
- int guideEnd,
- float guidePercent) throws IOException {
- writeVariable("orientation", orientation);
- writeVariable("guideBegin", guideBegin);
- writeVariable("guideEnd", guideEnd);
- writeVariable("guidePercent", guidePercent);
- }
-
- private void writeDimension(String dimString,
- int dim,
- int dimDefault,
- float dimPercent,
- int dimMin,
- int dimMax,
- boolean unusedConstrainedDim) throws IOException {
- if (dim == 0) {
- if (dimMax != UNSET || dimMin != UNSET) {
- String s = "-----";
- switch (dimDefault) {
- case 0: // spread
- s = INDENT + dimString + ": {value:'spread'";
- break;
- case 1: // wrap
- s = INDENT + dimString + ": {value:'wrap'";
- break;
- case 2: // percent
- s = INDENT + dimString + ": {value: '" + dimPercent + "%'";
- break;
- }
- if (dimMax != UNSET) {
- s += ", max: " + dimMax;
- }
- if (dimMax != UNSET) {
- s += ", min: " + dimMin;
- }
- s += "},\n";
- mWriter.write(s);
- return;
- }
-
- switch (dimDefault) {
- case 0: // spread is the default
- break;
- case 1: // wrap
- mWriter.write(INDENT + dimString + ": '???????????',\n");
- return;
- case 2: // percent
- mWriter.write(INDENT + dimString + ": '" + dimPercent + "%',\n");
- }
-
- } else if (dim == -2) {
- mWriter.write(INDENT + dimString + ": 'wrap',\n");
- } else if (dim == -1) {
- mWriter.write(INDENT + dimString + ": 'parent',\n");
- } else {
- mWriter.write(INDENT + dimString + ": " + dim + ",\n");
- }
- }
-
- private String getSimpleName(int id) {
- if (mIdMap.containsKey(id)) {
- return "" + mIdMap.get(id);
- }
- if (id == 0) {
- return "parent";
- }
- String name = lookup(id);
- mIdMap.put(id, name);
- return "" + name + "";
- }
-
- private String getName(int id) {
- return "'" + getSimpleName(id) + "'";
- }
-
- private String lookup(int id) {
- try {
- if (mNames.containsKey(id)) {
- return mNames.get(id);
- }
- if (id != -1) {
- return mContext.getResources().getResourceEntryName(id);
- } else {
- return "unknown" + ++mUnknownCount;
- }
- } catch (Exception ex) {
- return "unknown" + ++mUnknownCount;
- }
- }
-
- private void writeConstraint(String my,
- int constraint,
- String other,
- int margin,
- int goneMargin) throws IOException {
- if (constraint == UNSET) {
- return;
- }
- mWriter.write(INDENT + my);
- mWriter.write(":[");
- mWriter.write(getName(constraint));
- mWriter.write(", ");
- mWriter.write("'" + other + "'");
- if (margin != 0 || goneMargin != UNSET_GONE_MARGIN) {
- mWriter.write(", " + margin);
- if (goneMargin != UNSET_GONE_MARGIN) {
- mWriter.write(", " + goneMargin);
- }
- }
- mWriter.write("],\n");
- }
-
- private void writeCircle(int circleConstraint,
- float circleAngle,
- int circleRadius) throws IOException {
- if (circleConstraint == UNSET) {
- return;
- }
- mWriter.write(INDENT + "circle");
- mWriter.write(":[");
- mWriter.write(getName(circleConstraint));
- mWriter.write(", " + circleAngle);
- mWriter.write(circleRadius + "],\n");
- }
-
- private void writeVariable(String name, int value) throws IOException {
- if (value == 0 || value == -1) {
- return;
- }
- mWriter.write(INDENT + name);
- mWriter.write(": " + value);
- mWriter.write(",\n");
- }
-
- private void writeVariable(String name, float value) throws IOException {
- if (value == UNSET) {
- return;
- }
- mWriter.write(INDENT + name);
- mWriter.write(": " + value);
- mWriter.write(",\n");
- }
-
- private void writeVariable(String name, float value, float def) throws IOException {
- if (value == def) {
- return;
- }
- mWriter.write(INDENT + name);
- mWriter.write(": " + value);
- mWriter.write(",\n");
- }
-
- private void writeVariable(String name, boolean value, boolean def) throws IOException {
- if (value == def) {
- return;
- }
- mWriter.write(INDENT + name);
- mWriter.write(": " + value);
- mWriter.write(",\n");
- }
-
- private void writeVariable(String name, int[] value) throws IOException {
- if (value == null) {
- return;
- }
- mWriter.write(INDENT + name);
- mWriter.write(": ");
- for (int i = 0; i < value.length; i++) {
- mWriter.write(((i == 0) ? "[" : ", ") + getName(value[i]));
- }
- mWriter.write("],\n");
- }
-
- private void writeVariable(String name, String value) throws IOException {
- if (value == null) {
- return;
- }
- mWriter.write(INDENT + name);
- mWriter.write(": '" + value);
- mWriter.write("',\n");
- }
- }
-}
diff --git a/constraintlayout/constraintlayout/src/main/res/values/attrs.xml b/constraintlayout/constraintlayout/src/main/res/values/attrs.xml
index aba4fb6..d9029b17 100644
--- a/constraintlayout/constraintlayout/src/main/res/values/attrs.xml
+++ b/constraintlayout/constraintlayout/src/main/res/values/attrs.xml
@@ -816,21 +816,6 @@
</declare-styleable>
- <!-- This is the api for logging constraints in JSON5 format -->
- <declare-styleable name="LogJson">
- <attr name="logJsonTo" format="enum|string">
- <enum name="log" value="1" />
- <enum name="console" value="2" />
- </attr>
- <attr name="logJsonMode" format="enum">
- <enum name="periodic" value="1" />
- <enum name="delayed" value="2" />
- <enum name="layout" value="3" />
- <enum name="api" value="4" />
- </attr>
- <attr name="logJsonDelay" format="integer" />
- </declare-styleable>
-
<declare-styleable name="Constraint">
<attr name="android:orientation" />
<attr name="android:id" />
diff --git a/core/core-ktx/api/current.ignore b/core/core-ktx/api/current.ignore
new file mode 100644
index 0000000..6557477
--- /dev/null
+++ b/core/core-ktx/api/current.ignore
@@ -0,0 +1,17 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#containsValue(android.util.LongSparseArray<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.containsValue(android.util.LongSparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#getOrDefault(android.util.LongSparseArray<T>, long, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.LongSparseArrayKt.getOrDefault(android.util.LongSparseArray<T> arg1, long key, T defaultValue)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#remove(android.util.LongSparseArray<T>, long, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.remove(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#set(android.util.LongSparseArray<T>, long, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.set(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#containsValue(android.util.SparseArray<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.containsValue(android.util.SparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#getOrDefault(android.util.SparseArray<T>, int, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.SparseArrayKt.getOrDefault(android.util.SparseArray<T> arg1, int key, T defaultValue)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#remove(android.util.SparseArray<T>, int, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.remove(android.util.SparseArray<T> arg1, int key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#set(android.util.SparseArray<T>, int, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.set(android.util.SparseArray<T> arg1, int key, T value)
diff --git a/core/core-ktx/api/current.txt b/core/core-ktx/api/current.txt
index d3bbf86..89ab047 100644
--- a/core/core-ktx/api/current.txt
+++ b/core/core-ktx/api/current.txt
@@ -50,7 +50,7 @@
method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
- method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+ method public static inline <R> R use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
}
}
@@ -72,7 +72,7 @@
package androidx.core.database.sqlite {
public final class SQLiteDatabaseKt {
- method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+ method public static inline <T> T transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
}
}
@@ -333,7 +333,7 @@
}
public final class TraceKt {
- method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+ method @Deprecated public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
}
@@ -428,18 +428,18 @@
public final class LongSparseArrayKt {
method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
- method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+ method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T value);
method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
- method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
- method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method @RequiresApi(16) public static inline <T> T getOrDefault(android.util.LongSparseArray<T>, long key, T defaultValue);
+ method @RequiresApi(16) public static inline <T> T getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
- method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
- method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+ method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T value);
+ method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T value);
method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
}
@@ -448,10 +448,10 @@
}
public final class PairKt {
- method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
- method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
- method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
- method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+ method public static inline operator <F, S> F component1(androidx.core.util.Pair<F,S>);
+ method public static inline operator <F, S> F component1(android.util.Pair<F,S>);
+ method public static inline operator <F, S> S component2(androidx.core.util.Pair<F,S>);
+ method public static inline operator <F, S> S component2(android.util.Pair<F,S>);
method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
@@ -483,18 +483,18 @@
public final class SparseArrayKt {
method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
- method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+ method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T value);
method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
- method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(android.util.SparseArray<T>, int key, T defaultValue);
+ method public static inline <T> T getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(android.util.SparseArray<T>);
method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
- method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
- method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+ method public static <T> boolean remove(android.util.SparseArray<T>, int key, T value);
+ method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T value);
method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
}
diff --git a/core/core-ktx/api/public_plus_experimental_current.txt b/core/core-ktx/api/public_plus_experimental_current.txt
index d3bbf86..89ab047 100644
--- a/core/core-ktx/api/public_plus_experimental_current.txt
+++ b/core/core-ktx/api/public_plus_experimental_current.txt
@@ -50,7 +50,7 @@
method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
- method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+ method public static inline <R> R use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
}
}
@@ -72,7 +72,7 @@
package androidx.core.database.sqlite {
public final class SQLiteDatabaseKt {
- method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+ method public static inline <T> T transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
}
}
@@ -333,7 +333,7 @@
}
public final class TraceKt {
- method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+ method @Deprecated public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
}
@@ -428,18 +428,18 @@
public final class LongSparseArrayKt {
method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
- method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+ method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T value);
method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
- method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
- method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method @RequiresApi(16) public static inline <T> T getOrDefault(android.util.LongSparseArray<T>, long key, T defaultValue);
+ method @RequiresApi(16) public static inline <T> T getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
- method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
- method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+ method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T value);
+ method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T value);
method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
}
@@ -448,10 +448,10 @@
}
public final class PairKt {
- method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
- method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
- method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
- method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+ method public static inline operator <F, S> F component1(androidx.core.util.Pair<F,S>);
+ method public static inline operator <F, S> F component1(android.util.Pair<F,S>);
+ method public static inline operator <F, S> S component2(androidx.core.util.Pair<F,S>);
+ method public static inline operator <F, S> S component2(android.util.Pair<F,S>);
method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
@@ -483,18 +483,18 @@
public final class SparseArrayKt {
method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
- method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+ method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T value);
method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
- method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(android.util.SparseArray<T>, int key, T defaultValue);
+ method public static inline <T> T getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(android.util.SparseArray<T>);
method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
- method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
- method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+ method public static <T> boolean remove(android.util.SparseArray<T>, int key, T value);
+ method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T value);
method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
}
diff --git a/core/core-ktx/api/restricted_current.ignore b/core/core-ktx/api/restricted_current.ignore
new file mode 100644
index 0000000..6557477
--- /dev/null
+++ b/core/core-ktx/api/restricted_current.ignore
@@ -0,0 +1,17 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#containsValue(android.util.LongSparseArray<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.containsValue(android.util.LongSparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#getOrDefault(android.util.LongSparseArray<T>, long, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.LongSparseArrayKt.getOrDefault(android.util.LongSparseArray<T> arg1, long key, T defaultValue)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#remove(android.util.LongSparseArray<T>, long, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.remove(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.LongSparseArrayKt#set(android.util.LongSparseArray<T>, long, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.LongSparseArrayKt.set(android.util.LongSparseArray<T> arg1, long key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#containsValue(android.util.SparseArray<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.containsValue(android.util.SparseArray<T> arg1, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#getOrDefault(android.util.SparseArray<T>, int, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter defaultValue in androidx.core.util.SparseArrayKt.getOrDefault(android.util.SparseArray<T> arg1, int key, T defaultValue)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#remove(android.util.SparseArray<T>, int, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.remove(android.util.SparseArray<T> arg1, int key, T value)
+InvalidNullConversion: androidx.core.util.SparseArrayKt#set(android.util.SparseArray<T>, int, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.core.util.SparseArrayKt.set(android.util.SparseArray<T> arg1, int key, T value)
diff --git a/core/core-ktx/api/restricted_current.txt b/core/core-ktx/api/restricted_current.txt
index d3bbf86..89ab047 100644
--- a/core/core-ktx/api/restricted_current.txt
+++ b/core/core-ktx/api/restricted_current.txt
@@ -50,7 +50,7 @@
method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
- method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
+ method public static inline <R> R use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
}
}
@@ -72,7 +72,7 @@
package androidx.core.database.sqlite {
public final class SQLiteDatabaseKt {
- method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
+ method public static inline <T> T transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
}
}
@@ -333,7 +333,7 @@
}
public final class TraceKt {
- method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+ method @Deprecated public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
}
@@ -428,18 +428,18 @@
public final class LongSparseArrayKt {
method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
- method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
+ method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T value);
method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
- method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
- method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method @RequiresApi(16) public static inline <T> T getOrDefault(android.util.LongSparseArray<T>, long key, T defaultValue);
+ method @RequiresApi(16) public static inline <T> T getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
- method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
- method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
+ method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T value);
+ method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T value);
method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
}
@@ -448,10 +448,10 @@
}
public final class PairKt {
- method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
- method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
- method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
- method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
+ method public static inline operator <F, S> F component1(androidx.core.util.Pair<F,S>);
+ method public static inline operator <F, S> F component1(android.util.Pair<F,S>);
+ method public static inline operator <F, S> S component2(androidx.core.util.Pair<F,S>);
+ method public static inline operator <F, S> S component2(android.util.Pair<F,S>);
method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
@@ -483,18 +483,18 @@
public final class SparseArrayKt {
method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
- method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
+ method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T value);
method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
- method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
- method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+ method public static inline <T> T getOrDefault(android.util.SparseArray<T>, int key, T defaultValue);
+ method public static inline <T> T getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public static inline <T> int getSize(android.util.SparseArray<T>);
method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
- method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
- method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
+ method public static <T> boolean remove(android.util.SparseArray<T>, int key, T value);
+ method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T value);
method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
}
diff --git a/core/core-testing/api/current.txt b/core/core-testing/api/current.txt
index bca6bb8..40c6d07 100644
--- a/core/core-testing/api/current.txt
+++ b/core/core-testing/api/current.txt
@@ -3,7 +3,7 @@
public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
ctor public TestConsumer();
- method public void accept(T? t);
+ method public void accept(T t);
method public void assertValues(java.util.List<? extends T> values);
}
diff --git a/core/core-testing/api/public_plus_experimental_current.txt b/core/core-testing/api/public_plus_experimental_current.txt
index bca6bb8..40c6d07 100644
--- a/core/core-testing/api/public_plus_experimental_current.txt
+++ b/core/core-testing/api/public_plus_experimental_current.txt
@@ -3,7 +3,7 @@
public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
ctor public TestConsumer();
- method public void accept(T? t);
+ method public void accept(T t);
method public void assertValues(java.util.List<? extends T> values);
}
diff --git a/core/core-testing/api/restricted_current.txt b/core/core-testing/api/restricted_current.txt
index bca6bb8..40c6d07 100644
--- a/core/core-testing/api/restricted_current.txt
+++ b/core/core-testing/api/restricted_current.txt
@@ -3,7 +3,7 @@
public final class TestConsumer<T> implements androidx.core.util.Consumer<T> {
ctor public TestConsumer();
- method public void accept(T? t);
+ method public void accept(T t);
method public void assertValues(java.util.List<? extends T> values);
}
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 2c3c0b8..7ce3b2f 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -2172,6 +2172,14 @@
}
+package androidx.core.text.method {
+
+ public class LinkMovementMethodCompat extends android.text.method.LinkMovementMethod {
+ method public static androidx.core.text.method.LinkMovementMethodCompat getInstance();
+ }
+
+}
+
package androidx.core.text.util {
public final class LinkifyCompat {
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index 2be0c06..77a0578 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -2179,6 +2179,14 @@
}
+package androidx.core.text.method {
+
+ public class LinkMovementMethodCompat extends android.text.method.LinkMovementMethod {
+ method public static androidx.core.text.method.LinkMovementMethodCompat getInstance();
+ }
+
+}
+
package androidx.core.text.util {
public final class LinkifyCompat {
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index c860f39..5b50848 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -2547,6 +2547,14 @@
}
+package androidx.core.text.method {
+
+ public class LinkMovementMethodCompat extends android.text.method.LinkMovementMethod {
+ method public static androidx.core.text.method.LinkMovementMethodCompat getInstance();
+ }
+
+}
+
package androidx.core.text.util {
public final class LinkifyCompat {
diff --git a/core/core/src/androidTest/java/androidx/core/text/method/LinkMovementMethodCompatTest.java b/core/core/src/androidTest/java/androidx/core/text/method/LinkMovementMethodCompatTest.java
new file mode 100644
index 0000000..7eb6b39
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/text/method/LinkMovementMethodCompatTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.text.method;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.style.ClickableSpan;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.TestActivity;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test for {@link LinkMovementMethodCompat}.
+ *
+ * @see android.text.method.cts.LinkMovementMethodTest
+ */
+public class LinkMovementMethodCompatTest {
+ private static final String CONTENT = "clickable\nunclickable\nclickable";
+
+ private TestActivity mActivity;
+ private LinkMovementMethodCompat mMethod;
+ private TextView mView;
+ private Spannable mSpannable;
+ private ClickableSpan mClickable0;
+ private ClickableSpan mClickable1;
+
+ @Rule
+ public ActivityTestRule<TestActivity> mActivityRule =
+ new ActivityTestRule<>(TestActivity.class);
+
+ @Before
+ public void setup() throws Throwable {
+ mActivity = mActivityRule.getActivity();
+ mMethod = LinkMovementMethodCompat.getInstance();
+
+ // Set the content view with a text view which contains 3 lines,
+ mActivityRule.runOnUiThread(() -> mView = new TextViewNoIme(mActivity));
+ mView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
+ mView.setText(CONTENT, TextView.BufferType.SPANNABLE);
+
+ mActivityRule.runOnUiThread(() -> mActivity.setContentView(mView));
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ mSpannable = (Spannable) mView.getText();
+ // make first line clickable
+ mClickable0 = markClickable(0, CONTENT.indexOf('\n'));
+ // make last line clickable
+ mClickable1 = markClickable(CONTENT.lastIndexOf('\n'), CONTENT.length());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testOnTouchEvent() {
+ assertSelection(mSpannable, -1);
+
+ // press on first line (Clickable)
+ assertTrue(pressOnLine(0));
+ assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+ // release on first line
+ verify(mClickable0, never()).onClick(any());
+ assertTrue(releaseOnLine(0));
+ verify(mClickable0, times(1)).onClick(any());
+
+ // press on second line (unclickable)
+ assertSelectClickableLeftToRight(mSpannable, mClickable0);
+ // just clear selection
+ pressOnLine(1);
+ assertSelection(mSpannable, -1);
+
+ // press on last line (Clickable)
+ assertTrue(pressOnLine(2));
+ assertSelectClickableLeftToRight(mSpannable, mClickable1);
+
+ // release on last line
+ verify(mClickable1, never()).onClick(any());
+ assertTrue(releaseOnLine(2));
+ verify(mClickable1, times(1)).onClick(any());
+
+ // release on second line (unclickable)
+ assertSelectClickableLeftToRight(mSpannable, mClickable1);
+ // just clear selection
+ releaseOnLine(1);
+ assertSelection(mSpannable, -1);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testOnTouchEvent_outsideLineBounds() {
+ assertSelection(mSpannable, -1);
+
+ // press on first line (clickable)
+ assertTrue(pressOnLine(0));
+ assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+ // release above first line
+ float x = (mView.getLayout().getLineLeft(0) + mView.getLayout().getLineRight(0)) / 2f;
+ float y = -1f;
+ assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+ verify(mClickable0, never()).onClick(any());
+
+ // press on first line (clickable)
+ assertTrue(pressOnLine(0));
+ assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+ // release to left of first line
+ x = mView.getLayout().getLineLeft(0) - 1f;
+ y = (mView.getLayout().getLineTop(0) + mView.getLayout().getLineBottom(0)) / 2f;
+ assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+ verify(mClickable0, never()).onClick(any());
+
+ // press on first line (clickable)
+ assertTrue(pressOnLine(0));
+ assertSelectClickableLeftToRight(mSpannable, mClickable0);
+
+ // release to right of first line
+ x = mView.getLayout().getLineRight(0) + 1f;
+ y = (mView.getLayout().getLineTop(0) + mView.getLayout().getLineBottom(0)) / 2f;
+ assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+ verify(mClickable0, never()).onClick(any());
+
+ // press on last line (clickable)
+ assertTrue(pressOnLine(2));
+ assertSelectClickableLeftToRight(mSpannable, mClickable1);
+
+ // release below last line
+ x = (mView.getLayout().getLineLeft(0) + mView.getLayout().getLineRight(0)) / 2f;
+ y = mView.getLayout().getHeight() + 1f;
+ assertFalse(performMotionAtPoint(x, y, MotionEvent.ACTION_UP));
+ verify(mClickable1, never()).onClick(any());
+ }
+
+ private ClickableSpan markClickable(final int start, final int end) throws Throwable {
+ final ClickableSpan clickableSpan = spy(new MockClickableSpan());
+ mActivityRule.runOnUiThread(() -> mSpannable.setSpan(clickableSpan, start, end,
+ Spanned.SPAN_MARK_MARK));
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ return clickableSpan;
+ }
+
+ private boolean performMotionAtPoint(float x, float y, int action) {
+ long now = SystemClock.uptimeMillis();
+ return mMethod.onTouchEvent(mView, mSpannable,
+ MotionEvent.obtain(now, now, action, x, y, 0));
+ }
+
+ private boolean performMotionOnLine(int line, int action) {
+ float x = (mView.getLayout().getLineLeft(line) + mView.getLayout().getLineRight(line)) / 2f;
+ float y = (mView.getLayout().getLineTop(line) + mView.getLayout().getLineBottom(line)) / 2f;
+ return performMotionAtPoint(x, y, action);
+ }
+
+ private boolean pressOnLine(int line) {
+ return performMotionOnLine(line, MotionEvent.ACTION_DOWN);
+ }
+
+ private boolean releaseOnLine(int line) {
+ return performMotionOnLine(line, MotionEvent.ACTION_UP);
+ }
+
+ private void assertSelection(Spannable spannable, int start, int end) {
+ assertEquals(start, Selection.getSelectionStart(spannable));
+ assertEquals(end, Selection.getSelectionEnd(spannable));
+ }
+
+ private void assertSelection(Spannable spannable, int position) {
+ assertSelection(spannable, position, position);
+ }
+
+ private void assertSelectClickableLeftToRight(Spannable spannable,
+ ClickableSpan clickableSpan) {
+ assertSelection(spannable, spannable.getSpanStart(clickableSpan),
+ spannable.getSpanEnd(clickableSpan));
+ }
+
+ public static class TextViewNoIme extends TextView {
+ public TextViewNoIme(@NonNull Context context) {
+ super(context);
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ return null;
+ }
+ }
+
+ public static class MockClickableSpan extends ClickableSpan {
+ @Override
+ public void onClick(View widget) {}
+ }
+}
diff --git a/core/core/src/main/java/androidx/core/text/method/LinkMovementMethodCompat.java b/core/core/src/main/java/androidx/core/text/method/LinkMovementMethodCompat.java
new file mode 100644
index 0000000..f783934
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/text/method/LinkMovementMethodCompat.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.text.method;
+
+import android.text.Layout;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.method.LinkMovementMethod;
+import android.text.method.Touch;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.core.os.BuildCompat;
+
+/**
+ * Backwards compatible version of {@link LinkMovementMethod} which fixes the issue that links can
+ * be triggered for touches outside of line bounds before Android V.
+ */
+public class LinkMovementMethodCompat extends LinkMovementMethod {
+ private static LinkMovementMethodCompat sInstance;
+
+ private LinkMovementMethodCompat() {}
+
+ @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+ @Override
+ public boolean onTouchEvent(@Nullable TextView widget, @Nullable Spannable buffer,
+ @Nullable MotionEvent event) {
+ if (!BuildCompat.isAtLeastV()) {
+ int action = event.getAction();
+
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
+ int x = (int) event.getX();
+ int y = (int) event.getY();
+
+ x -= widget.getTotalPaddingLeft();
+ y -= widget.getTotalPaddingTop();
+
+ x += widget.getScrollX();
+ y += widget.getScrollY();
+
+ Layout layout = widget.getLayout();
+ boolean isOutOfLineBounds;
+ if (y < 0 || y > layout.getHeight()) {
+ isOutOfLineBounds = true;
+ } else {
+ int line = layout.getLineForVertical(y);
+ isOutOfLineBounds = x < layout.getLineLeft(line)
+ || x > layout.getLineRight(line);
+ }
+
+ if (isOutOfLineBounds) {
+ Selection.removeSelection(buffer);
+
+ // The same as super.onTouchEvent() in LinkMovementMethod.onTouchEvent(), i.e.
+ // ScrollingMovementMethod.onTouchEvent().
+ return Touch.onTouchEvent(widget, buffer, event);
+ }
+ }
+ }
+
+ return super.onTouchEvent(widget, buffer, event);
+ }
+
+ /**
+ * Retrieves the singleton instance of {@link LinkMovementMethodCompat}.
+ *
+ * @return the singleton instance of {@link LinkMovementMethodCompat}
+ */
+ @NonNull
+ public static LinkMovementMethodCompat getInstance() {
+ if (sInstance == null) {
+ sInstance = new LinkMovementMethodCompat();
+ }
+
+ return sInstance;
+ }
+}
diff --git a/credentials/credentials/api/api_lint.ignore b/credentials/credentials/api/api_lint.ignore
index 1b0526a3..be1a990 100644
--- a/credentials/credentials/api/api_lint.ignore
+++ b/credentials/credentials/api/api_lint.ignore
@@ -1,4 +1,5 @@
// Baseline format: 1.0
-GenericCallbacks: androidx.credentials.CredentialManagerCallback:
- CredentialManagerCallback can be replaced with OutcomeReceiver<R,E> (platform) or suspend fun / ListenableFuture (AndroidX).
-Unnecessary safe call on a non-null receiver of type Bundle
+GetterSetterNames: field CreatePublicKeyCredentialRequest.preferImmediatelyAvailableCredentials:
+ Invalid name for boolean property `preferImmediatelyAvailableCredentials`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field GetPublicKeyCredentialOption.preferImmediatelyAvailableCredentials:
+ Invalid name for boolean property `preferImmediatelyAvailableCredentials`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/credentials/credentials/api/current.txt b/credentials/credentials/api/current.txt
index 0ccc2b2..d15ea9a 100644
--- a/credentials/credentials/api/current.txt
+++ b/credentials/credentials/api/current.txt
@@ -98,7 +98,7 @@
public interface CredentialManagerCallback<R, E> {
method public void onError(E e);
- method public void onResult(R? result);
+ method public void onResult(R result);
}
public abstract class CredentialOption {
diff --git a/credentials/credentials/api/public_plus_experimental_current.txt b/credentials/credentials/api/public_plus_experimental_current.txt
index 0ccc2b2..d15ea9a 100644
--- a/credentials/credentials/api/public_plus_experimental_current.txt
+++ b/credentials/credentials/api/public_plus_experimental_current.txt
@@ -98,7 +98,7 @@
public interface CredentialManagerCallback<R, E> {
method public void onError(E e);
- method public void onResult(R? result);
+ method public void onResult(R result);
}
public abstract class CredentialOption {
diff --git a/credentials/credentials/api/restricted_current.txt b/credentials/credentials/api/restricted_current.txt
index 0ccc2b2..d15ea9a 100644
--- a/credentials/credentials/api/restricted_current.txt
+++ b/credentials/credentials/api/restricted_current.txt
@@ -98,7 +98,7 @@
public interface CredentialManagerCallback<R, E> {
method public void onError(E e);
- method public void onResult(R? result);
+ method public void onResult(R result);
}
public abstract class CredentialOption {
diff --git a/datastore/datastore-core/api/current.ignore b/datastore/datastore-core/api/current.ignore
index c6d6684..9d477c1 100644
--- a/datastore/datastore-core/api/current.ignore
+++ b/datastore/datastore-core/api/current.ignore
@@ -1,4 +1,12 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.core.DataMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+InvalidNullConversion: androidx.datastore.core.Serializer#writeTo(T, java.io.OutputStream, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.datastore.core.Serializer.writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit> arg3)
+
+
ParameterNameChange: androidx.datastore.core.DataMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
Attempted to remove parameter name from parameter arg1 in androidx.datastore.core.DataMigration.cleanUp
ParameterNameChange: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore-core/api/current.txt b/datastore/datastore-core/api/current.txt
index 64fe57a..64db9d6 100644
--- a/datastore/datastore-core/api/current.txt
+++ b/datastore/datastore-core/api/current.txt
@@ -6,7 +6,7 @@
}
public final class CloseableKt {
- method public static inline <T extends androidx.datastore.core.Closeable, R> R! use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.datastore.core.Closeable, R> R use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
}
public final class CorruptionException extends java.io.IOException {
@@ -15,8 +15,8 @@
public interface DataMigration<T> {
method public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+ method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+ method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}
public interface DataStore<T> {
@@ -60,10 +60,10 @@
}
public interface Serializer<T> {
- method public T! getDefaultValue();
+ method public T getDefaultValue();
method public suspend Object? readFrom(java.io.InputStream input, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? writeTo(T? t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- property public abstract T! defaultValue;
+ method public suspend Object? writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ property public abstract T defaultValue;
}
public interface Storage<T> {
@@ -79,11 +79,11 @@
public final class StorageConnectionKt {
method public static suspend <T> Object? readData(androidx.datastore.core.StorageConnection<T>, kotlin.coroutines.Continuation<? super T>);
- method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
public interface WriteScope<T> extends androidx.datastore.core.ReadScope<T> {
- method public suspend Object? writeData(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? writeData(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
}
diff --git a/datastore/datastore-core/api/public_plus_experimental_current.txt b/datastore/datastore-core/api/public_plus_experimental_current.txt
index 3ef2791..0518771 100644
--- a/datastore/datastore-core/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-core/api/public_plus_experimental_current.txt
@@ -6,7 +6,7 @@
}
public final class CloseableKt {
- method public static inline <T extends androidx.datastore.core.Closeable, R> R! use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.datastore.core.Closeable, R> R use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
}
public final class CorruptionException extends java.io.IOException {
@@ -15,8 +15,8 @@
public interface DataMigration<T> {
method public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+ method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+ method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}
public interface DataStore<T> {
@@ -71,10 +71,10 @@
}
public interface Serializer<T> {
- method public T! getDefaultValue();
+ method public T getDefaultValue();
method public suspend Object? readFrom(java.io.InputStream input, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? writeTo(T? t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- property public abstract T! defaultValue;
+ method public suspend Object? writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ property public abstract T defaultValue;
}
public interface Storage<T> {
@@ -90,11 +90,11 @@
public final class StorageConnectionKt {
method public static suspend <T> Object? readData(androidx.datastore.core.StorageConnection<T>, kotlin.coroutines.Continuation<? super T>);
- method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
public interface WriteScope<T> extends androidx.datastore.core.ReadScope<T> {
- method public suspend Object? writeData(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? writeData(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
}
diff --git a/datastore/datastore-core/api/restricted_current.ignore b/datastore/datastore-core/api/restricted_current.ignore
index c6d6684..9d477c1 100644
--- a/datastore/datastore-core/api/restricted_current.ignore
+++ b/datastore/datastore-core/api/restricted_current.ignore
@@ -1,4 +1,12 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.core.DataMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.core.DataMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+InvalidNullConversion: androidx.datastore.core.Serializer#writeTo(T, java.io.OutputStream, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.datastore.core.Serializer.writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit> arg3)
+
+
ParameterNameChange: androidx.datastore.core.DataMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
Attempted to remove parameter name from parameter arg1 in androidx.datastore.core.DataMigration.cleanUp
ParameterNameChange: androidx.datastore.core.DataMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore-core/api/restricted_current.txt b/datastore/datastore-core/api/restricted_current.txt
index 64fe57a..64db9d6 100644
--- a/datastore/datastore-core/api/restricted_current.txt
+++ b/datastore/datastore-core/api/restricted_current.txt
@@ -6,7 +6,7 @@
}
public final class CloseableKt {
- method public static inline <T extends androidx.datastore.core.Closeable, R> R! use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+ method public static inline <T extends androidx.datastore.core.Closeable, R> R use(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
}
public final class CorruptionException extends java.io.IOException {
@@ -15,8 +15,8 @@
public interface DataMigration<T> {
method public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+ method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+ method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}
public interface DataStore<T> {
@@ -60,10 +60,10 @@
}
public interface Serializer<T> {
- method public T! getDefaultValue();
+ method public T getDefaultValue();
method public suspend Object? readFrom(java.io.InputStream input, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? writeTo(T? t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- property public abstract T! defaultValue;
+ method public suspend Object? writeTo(T t, java.io.OutputStream output, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ property public abstract T defaultValue;
}
public interface Storage<T> {
@@ -79,11 +79,11 @@
public final class StorageConnectionKt {
method public static suspend <T> Object? readData(androidx.datastore.core.StorageConnection<T>, kotlin.coroutines.Continuation<? super T>);
- method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public static suspend <T> Object? writeData(androidx.datastore.core.StorageConnection<T>, T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
public interface WriteScope<T> extends androidx.datastore.core.ReadScope<T> {
- method public suspend Object? writeData(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? writeData(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
}
}
diff --git a/datastore/datastore-preferences-core/api/current.ignore b/datastore/datastore-preferences-core/api/current.ignore
index 92ab16a..dcd14f6 100644
--- a/datastore/datastore-preferences-core/api/current.ignore
+++ b/datastore/datastore-preferences-core/api/current.ignore
@@ -1,3 +1,9 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.preferences.core.MutablePreferences#set(androidx.datastore.preferences.core.Preferences.Key<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.MutablePreferences.set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value)
+InvalidNullConversion: androidx.datastore.preferences.core.Preferences.Key#to(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.Preferences.Key.to(T value)
+
+
ParameterNameChange: androidx.datastore.preferences.core.PreferencesKt#edit(androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences>, kotlin.jvm.functions.Function2<? super androidx.datastore.preferences.core.MutablePreferences,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>, kotlin.coroutines.Continuation<? super androidx.datastore.preferences.core.Preferences>) parameter #2:
Attempted to remove parameter name from parameter arg3 in androidx.datastore.preferences.core.PreferencesKt.edit
diff --git a/datastore/datastore-preferences-core/api/current.txt b/datastore/datastore-preferences-core/api/current.txt
index cdc92af..d3e249b 100644
--- a/datastore/datastore-preferences-core/api/current.txt
+++ b/datastore/datastore-preferences-core/api/current.txt
@@ -10,8 +10,8 @@
method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<?> pair);
method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<?>... pairs);
- method public <T> T! remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
- method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T? value);
+ method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
+ method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
}
public final class PreferenceDataStoreFactory {
@@ -34,7 +34,7 @@
public static final class Preferences.Key<T> {
method public String getName();
- method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
+ method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T value);
property public final String name;
}
diff --git a/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt b/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt
index cdc92af..d3e249b 100644
--- a/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-preferences-core/api/public_plus_experimental_current.txt
@@ -10,8 +10,8 @@
method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<?> pair);
method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<?>... pairs);
- method public <T> T! remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
- method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T? value);
+ method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
+ method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
}
public final class PreferenceDataStoreFactory {
@@ -34,7 +34,7 @@
public static final class Preferences.Key<T> {
method public String getName();
- method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
+ method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T value);
property public final String name;
}
diff --git a/datastore/datastore-preferences-core/api/restricted_current.ignore b/datastore/datastore-preferences-core/api/restricted_current.ignore
index 92ab16a..dcd14f6 100644
--- a/datastore/datastore-preferences-core/api/restricted_current.ignore
+++ b/datastore/datastore-preferences-core/api/restricted_current.ignore
@@ -1,3 +1,9 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.preferences.core.MutablePreferences#set(androidx.datastore.preferences.core.Preferences.Key<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.MutablePreferences.set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value)
+InvalidNullConversion: androidx.datastore.preferences.core.Preferences.Key#to(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.datastore.preferences.core.Preferences.Key.to(T value)
+
+
ParameterNameChange: androidx.datastore.preferences.core.PreferencesKt#edit(androidx.datastore.core.DataStore<androidx.datastore.preferences.core.Preferences>, kotlin.jvm.functions.Function2<? super androidx.datastore.preferences.core.MutablePreferences,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>, kotlin.coroutines.Continuation<? super androidx.datastore.preferences.core.Preferences>) parameter #2:
Attempted to remove parameter name from parameter arg3 in androidx.datastore.preferences.core.PreferencesKt.edit
diff --git a/datastore/datastore-preferences-core/api/restricted_current.txt b/datastore/datastore-preferences-core/api/restricted_current.txt
index cdc92af..d3e249b 100644
--- a/datastore/datastore-preferences-core/api/restricted_current.txt
+++ b/datastore/datastore-preferences-core/api/restricted_current.txt
@@ -10,8 +10,8 @@
method public operator void plusAssign(androidx.datastore.preferences.core.Preferences prefs);
method public operator void plusAssign(androidx.datastore.preferences.core.Preferences.Pair<?> pair);
method public void putAll(androidx.datastore.preferences.core.Preferences.Pair<?>... pairs);
- method public <T> T! remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
- method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T? value);
+ method public <T> T remove(androidx.datastore.preferences.core.Preferences.Key<T> key);
+ method public operator <T> void set(androidx.datastore.preferences.core.Preferences.Key<T> key, T value);
}
public final class PreferenceDataStoreFactory {
@@ -34,7 +34,7 @@
public static final class Preferences.Key<T> {
method public String getName();
- method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T? value);
+ method public infix androidx.datastore.preferences.core.Preferences.Pair<T> to(T value);
property public final String name;
}
diff --git a/datastore/datastore-rxjava2/api/current.ignore b/datastore/datastore-rxjava2/api/current.ignore
new file mode 100644
index 0000000..2b1768d
--- /dev/null
+++ b/datastore/datastore-rxjava2/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava2/api/current.txt b/datastore/datastore-rxjava2/api/current.txt
index dc394de..0f8fead 100644
--- a/datastore/datastore-rxjava2/api/current.txt
+++ b/datastore/datastore-rxjava2/api/current.txt
@@ -28,8 +28,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
- method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
- method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+ method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+ method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T currentData);
}
public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt b/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
index fb412f3..50486f6 100644
--- a/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-rxjava2/api/public_plus_experimental_current.txt
@@ -30,8 +30,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
- method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
- method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+ method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+ method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T currentData);
}
public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava2/api/restricted_current.ignore b/datastore/datastore-rxjava2/api/restricted_current.ignore
new file mode 100644
index 0000000..2b1768d
--- /dev/null
+++ b/datastore/datastore-rxjava2/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava2.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava2.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava2/api/restricted_current.txt b/datastore/datastore-rxjava2/api/restricted_current.txt
index dc394de..0f8fead 100644
--- a/datastore/datastore-rxjava2/api/restricted_current.txt
+++ b/datastore/datastore-rxjava2/api/restricted_current.txt
@@ -28,8 +28,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
- method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
- method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+ method public io.reactivex.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+ method public default io.reactivex.Single<java.lang.Boolean> shouldMigrate(T currentData);
}
public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava3/api/current.ignore b/datastore/datastore-rxjava3/api/current.ignore
new file mode 100644
index 0000000..624856f
--- /dev/null
+++ b/datastore/datastore-rxjava3/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava3/api/current.txt b/datastore/datastore-rxjava3/api/current.txt
index 218d1e9..ae8528e 100644
--- a/datastore/datastore-rxjava3/api/current.txt
+++ b/datastore/datastore-rxjava3/api/current.txt
@@ -28,8 +28,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
- method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
- method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+ method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+ method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T currentData);
}
public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt b/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt
index 025e898..c451a45 100644
--- a/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt
+++ b/datastore/datastore-rxjava3/api/public_plus_experimental_current.txt
@@ -30,8 +30,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
- method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
- method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+ method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+ method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T currentData);
}
public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore-rxjava3/api/restricted_current.ignore b/datastore/datastore-rxjava3/api/restricted_current.ignore
new file mode 100644
index 0000000..624856f
--- /dev/null
+++ b/datastore/datastore-rxjava3/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#migrate(androidx.datastore.migrations.SharedPreferencesView, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData)
+InvalidNullConversion: androidx.datastore.rxjava3.RxSharedPreferencesMigration#shouldMigrate(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.rxjava3.RxSharedPreferencesMigration.shouldMigrate(T currentData)
diff --git a/datastore/datastore-rxjava3/api/restricted_current.txt b/datastore/datastore-rxjava3/api/restricted_current.txt
index 218d1e9..ae8528e 100644
--- a/datastore/datastore-rxjava3/api/restricted_current.txt
+++ b/datastore/datastore-rxjava3/api/restricted_current.txt
@@ -28,8 +28,8 @@
}
@kotlin.jvm.JvmDefaultWithCompatibility public interface RxSharedPreferencesMigration<T> {
- method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T? currentData);
- method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T? currentData);
+ method public io.reactivex.rxjava3.core.Single<T> migrate(androidx.datastore.migrations.SharedPreferencesView sharedPreferencesView, T currentData);
+ method public default io.reactivex.rxjava3.core.Single<java.lang.Boolean> shouldMigrate(T currentData);
}
public final class RxSharedPreferencesMigrationBuilder<T> {
diff --git a/datastore/datastore/api/current.ignore b/datastore/datastore/api/current.ignore
index 7141632..a3186a11 100644
--- a/datastore/datastore/api/current.ignore
+++ b/datastore/datastore/api/current.ignore
@@ -1,4 +1,10 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+
+
ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
Attempted to remove parameter name from parameter arg1 in androidx.datastore.migrations.SharedPreferencesMigration.cleanUp
ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore/api/current.txt b/datastore/datastore/api/current.txt
index c4a6933..91d9597 100644
--- a/datastore/datastore/api/current.txt
+++ b/datastore/datastore/api/current.txt
@@ -21,8 +21,8 @@
ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, optional java.util.Set<java.lang.String> keysToMigrate, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) throws java.io.IOException;
- method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+ method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+ method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}
public final class SharedPreferencesView {
diff --git a/datastore/datastore/api/public_plus_experimental_current.txt b/datastore/datastore/api/public_plus_experimental_current.txt
index c4a6933..91d9597 100644
--- a/datastore/datastore/api/public_plus_experimental_current.txt
+++ b/datastore/datastore/api/public_plus_experimental_current.txt
@@ -21,8 +21,8 @@
ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, optional java.util.Set<java.lang.String> keysToMigrate, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) throws java.io.IOException;
- method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+ method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+ method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}
public final class SharedPreferencesView {
diff --git a/datastore/datastore/api/restricted_current.ignore b/datastore/datastore/api/restricted_current.ignore
index 7141632..a3186a11 100644
--- a/datastore/datastore/api/restricted_current.ignore
+++ b/datastore/datastore/api/restricted_current.ignore
@@ -1,4 +1,10 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.migrate(T currentData, kotlin.coroutines.Continuation<? super T> arg2)
+InvalidNullConversion: androidx.datastore.migrations.SharedPreferencesMigration#shouldMigrate(T, kotlin.coroutines.Continuation<? super java.lang.Boolean>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter currentData in androidx.datastore.migrations.SharedPreferencesMigration.shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean> arg2)
+
+
ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
Attempted to remove parameter name from parameter arg1 in androidx.datastore.migrations.SharedPreferencesMigration.cleanUp
ParameterNameChange: androidx.datastore.migrations.SharedPreferencesMigration#migrate(T, kotlin.coroutines.Continuation<? super T>) parameter #1:
diff --git a/datastore/datastore/api/restricted_current.txt b/datastore/datastore/api/restricted_current.txt
index c4a6933..91d9597 100644
--- a/datastore/datastore/api/restricted_current.txt
+++ b/datastore/datastore/api/restricted_current.txt
@@ -21,8 +21,8 @@
ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, optional java.util.Set<java.lang.String> keysToMigrate, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
ctor public SharedPreferencesMigration(android.content.Context context, String sharedPreferencesName, kotlin.jvm.functions.Function3<? super androidx.datastore.migrations.SharedPreferencesView,? super T,? super kotlin.coroutines.Continuation<? super T>,?> migrate);
method @kotlin.jvm.Throws(exceptionClasses=IOException::class) public suspend Object? cleanUp(kotlin.coroutines.Continuation<? super kotlin.Unit>) throws java.io.IOException;
- method public suspend Object? migrate(T? currentData, kotlin.coroutines.Continuation<? super T>);
- method public suspend Object? shouldMigrate(T? currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+ method public suspend Object? migrate(T currentData, kotlin.coroutines.Continuation<? super T>);
+ method public suspend Object? shouldMigrate(T currentData, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}
public final class SharedPreferencesView {
diff --git a/development/update-verification-metadata.sh b/development/update-verification-metadata.sh
index 90720f2..4820585 100755
--- a/development/update-verification-metadata.sh
+++ b/development/update-verification-metadata.sh
@@ -17,15 +17,17 @@
echo "regenerating verification metadata and keyring"
# regenerate metadata
# Need to run a clean build, https://github.com/gradle/gradle/issues/19228
- runGradle --stacktrace --write-verification-metadata pgp,sha256 --export-keys --dry-run --clean bOS :docs-kmp:zipCombinedKmpDocs
+ runGradle --stacktrace --write-verification-metadata pgp,sha256 --export-keys --dry-run --clean -Pandroidx.update.signatures=true bOS :docs-kmp:zipCombinedKmpDocs
# update verification metadata file
# also remove 'version=' lines, https://github.com/gradle/gradle/issues/20192
cat gradle/verification-metadata.dryrun.xml | sed 's/ \(trusted-key.*\)version="[^"]*"/\1/' > gradle/verification-metadata.xml
+ # rename keyring
+ mv gradle/verification-keyring-dryrun.keys gradle/verification-keyring.keys
+
# remove temporary files
rm -f gradle/verification-keyring-dryrun.gpg
- rm -f gradle/verification-keyring-dryrun.keys
rm -f gradle/verification-metadata.dryrun.xml
}
regenerateVerificationMetadata
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index fbe7d81..54c5515 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -402,7 +402,7 @@
samples("androidx.wear:wear-input-samples:1.2.0-alpha01")
docs("androidx.wear:wear-input-testing:1.2.0-alpha02")
docs("androidx.webkit:webkit:1.7.0-beta01")
- docs("androidx.window.extensions.core:core:1.0.0-beta02")
+ docs("androidx.window.extensions.core:core:1.0.0-rc01")
docs("androidx.window:window:1.1.0-beta02")
stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
docs("androidx.window:window-core:1.1.0-beta02")
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index 1b401fe..20df0bf 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -171,6 +171,7 @@
docs(project(":fragment:fragment-testing"))
docs(project(":glance:glance"))
docs(project(":glance:glance-appwidget"))
+ samples(project(":glance:glance-appwidget:glance-appwidget-samples"))
docs(project(":glance:glance-wear-tiles"))
docs(project(":graphics:filters:filters"))
docs(project(":graphics:graphics-core"))
@@ -367,7 +368,7 @@
docs(project(":window:window-rxjava2"))
docs(project(":window:window-rxjava3"))
stubs(project(":window:sidecar:sidecar"))
- samples(project(":window:window-samples:"))
+ samples(project(":window:window-samples"))
stubs(project(":window:extensions:extensions"))
stubs(project(":window:extensions:core:core"))
docs(project(":window:window-testing"))
diff --git a/enterprise/enterprise-feedback-testing/build.gradle b/enterprise/enterprise-feedback-testing/build.gradle
index 643fe67..184a4d1 100644
--- a/enterprise/enterprise-feedback-testing/build.gradle
+++ b/enterprise/enterprise-feedback-testing/build.gradle
@@ -21,7 +21,7 @@
id("com.android.library")
}
dependencies {
- api(project(":enterprise:enterprise-feedback:"))
+ api(project(":enterprise:enterprise-feedback"))
testImplementation(libs.truth)
}
android {
diff --git a/fragment/fragment/api/1.6.0-beta01.txt b/fragment/fragment/api/1.6.0-beta01.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/1.6.0-beta01.txt
+++ b/fragment/fragment/api/1.6.0-beta01.txt
@@ -196,7 +196,7 @@
ctor public FragmentContainerView(android.content.Context context);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
- method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+ method public <F extends androidx.fragment.app.Fragment> F getFragment();
}
public class FragmentController {
diff --git a/fragment/fragment/api/current.txt b/fragment/fragment/api/current.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/current.txt
+++ b/fragment/fragment/api/current.txt
@@ -196,7 +196,7 @@
ctor public FragmentContainerView(android.content.Context context);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
- method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+ method public <F extends androidx.fragment.app.Fragment> F getFragment();
}
public class FragmentController {
diff --git a/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt b/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt
+++ b/fragment/fragment/api/public_plus_experimental_1.6.0-beta01.txt
@@ -196,7 +196,7 @@
ctor public FragmentContainerView(android.content.Context context);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
- method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+ method public <F extends androidx.fragment.app.Fragment> F getFragment();
}
public class FragmentController {
diff --git a/fragment/fragment/api/public_plus_experimental_current.txt b/fragment/fragment/api/public_plus_experimental_current.txt
index 2f167cf..4d44df2 100644
--- a/fragment/fragment/api/public_plus_experimental_current.txt
+++ b/fragment/fragment/api/public_plus_experimental_current.txt
@@ -196,7 +196,7 @@
ctor public FragmentContainerView(android.content.Context context);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
- method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+ method public <F extends androidx.fragment.app.Fragment> F getFragment();
}
public class FragmentController {
diff --git a/fragment/fragment/api/restricted_1.6.0-beta01.txt b/fragment/fragment/api/restricted_1.6.0-beta01.txt
index 83801ad..369fe63 100644
--- a/fragment/fragment/api/restricted_1.6.0-beta01.txt
+++ b/fragment/fragment/api/restricted_1.6.0-beta01.txt
@@ -200,7 +200,7 @@
ctor public FragmentContainerView(android.content.Context context);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
- method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+ method public <F extends androidx.fragment.app.Fragment> F getFragment();
}
public class FragmentController {
diff --git a/fragment/fragment/api/restricted_current.txt b/fragment/fragment/api/restricted_current.txt
index 83801ad..369fe63 100644
--- a/fragment/fragment/api/restricted_current.txt
+++ b/fragment/fragment/api/restricted_current.txt
@@ -200,7 +200,7 @@
ctor public FragmentContainerView(android.content.Context context);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
- method public <F extends androidx.fragment.app.Fragment> F! getFragment();
+ method public <F extends androidx.fragment.app.Fragment> F getFragment();
}
public class FragmentController {
diff --git a/glance/glance-appwidget/api/current.txt b/glance/glance-appwidget/api/current.txt
index ca32bb4..72717d0 100644
--- a/glance/glance-appwidget/api/current.txt
+++ b/glance/glance-appwidget/api/current.txt
@@ -24,9 +24,13 @@
public final class CheckBoxKt {
method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(long checkedColor, long uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors();
+ }
+
+ public final class CheckboxDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+ field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
}
public final class CircularProgressIndicatorKt {
@@ -45,11 +49,10 @@
public abstract class GlanceAppWidget {
ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
- method @Deprecated @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public void Content();
method public androidx.glance.appwidget.SizeMode getSizeMode();
method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
property public androidx.glance.appwidget.SizeMode sizeMode;
property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
@@ -102,12 +105,16 @@
public final class RadioButtonColors {
}
+ public final class RadioButtonDefaults {
+ method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+ method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+ field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+ }
+
public final class RadioButtonKt {
method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
- method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
- method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(long checkedColor, long uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.RadioButtonColors radioButtonColors();
method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
}
@@ -131,11 +138,15 @@
public abstract sealed class SwitchColors {
}
+ public final class SwitchDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+ field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+ }
+
public final class SwitchKt {
method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors();
}
}
diff --git a/glance/glance-appwidget/api/public_plus_experimental_current.txt b/glance/glance-appwidget/api/public_plus_experimental_current.txt
index 7143945..4ac3223 100644
--- a/glance/glance-appwidget/api/public_plus_experimental_current.txt
+++ b/glance/glance-appwidget/api/public_plus_experimental_current.txt
@@ -24,9 +24,13 @@
public final class CheckBoxKt {
method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(long checkedColor, long uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors();
+ }
+
+ public final class CheckboxDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+ field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
}
public final class CircularProgressIndicatorKt {
@@ -48,11 +52,10 @@
public abstract class GlanceAppWidget {
ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
- method @Deprecated @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public void Content();
method public androidx.glance.appwidget.SizeMode getSizeMode();
method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
property public androidx.glance.appwidget.SizeMode sizeMode;
property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
@@ -110,12 +113,16 @@
public final class RadioButtonColors {
}
+ public final class RadioButtonDefaults {
+ method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+ method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+ field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+ }
+
public final class RadioButtonKt {
method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
- method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
- method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(long checkedColor, long uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.RadioButtonColors radioButtonColors();
method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
}
@@ -145,11 +152,15 @@
public abstract sealed class SwitchColors {
}
+ public final class SwitchDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+ field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+ }
+
public final class SwitchKt {
method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors();
}
}
diff --git a/glance/glance-appwidget/api/restricted_current.txt b/glance/glance-appwidget/api/restricted_current.txt
index ca32bb4..72717d0 100644
--- a/glance/glance-appwidget/api/restricted_current.txt
+++ b/glance/glance-appwidget/api/restricted_current.txt
@@ -24,9 +24,13 @@
public final class CheckBoxKt {
method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void CheckBox(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.CheckBoxColors colors, optional int maxLines);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(long checkedColor, long uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.CheckBoxColors checkBoxColors();
+ }
+
+ public final class CheckboxDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors(long checkedColor, long uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.CheckBoxColors colors();
+ field public static final androidx.glance.appwidget.CheckboxDefaults INSTANCE;
}
public final class CircularProgressIndicatorKt {
@@ -45,11 +49,10 @@
public abstract class GlanceAppWidget {
ctor public GlanceAppWidget(optional @LayoutRes int errorUiLayout);
- method @Deprecated @androidx.compose.runtime.Composable @androidx.glance.GlanceComposable public void Content();
method public androidx.glance.appwidget.SizeMode getSizeMode();
method public androidx.glance.state.GlanceStateDefinition<?>? getStateDefinition();
method public suspend Object? onDelete(android.content.Context context, androidx.glance.GlanceId glanceId, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public abstract suspend Object? provideGlance(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public final suspend Object? update(android.content.Context context, androidx.glance.GlanceId id, kotlin.coroutines.Continuation<? super kotlin.Unit>);
property public androidx.glance.appwidget.SizeMode sizeMode;
property public androidx.glance.state.GlanceStateDefinition<?>? stateDefinition;
@@ -102,12 +105,16 @@
public final class RadioButtonColors {
}
+ public final class RadioButtonDefaults {
+ method public androidx.glance.appwidget.RadioButtonColors colors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
+ method public androidx.glance.appwidget.RadioButtonColors colors(long checkedColor, long uncheckedColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.RadioButtonColors colors();
+ field public static final androidx.glance.appwidget.RadioButtonDefaults INSTANCE;
+ }
+
public final class RadioButtonKt {
method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, androidx.glance.action.Action? onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void RadioButton(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.RadioButtonColors colors, optional int maxLines);
- method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(androidx.glance.unit.ColorProvider checkedColor, androidx.glance.unit.ColorProvider uncheckedColor);
- method public static androidx.glance.appwidget.RadioButtonColors radioButtonColors(long checkedColor, long uncheckedColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.RadioButtonColors radioButtonColors();
method public static androidx.glance.GlanceModifier selectableGroup(androidx.glance.GlanceModifier);
}
@@ -131,11 +138,15 @@
public abstract sealed class SwitchColors {
}
+ public final class SwitchDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
+ method @androidx.compose.runtime.Composable public androidx.glance.appwidget.SwitchColors colors();
+ field public static final androidx.glance.appwidget.SwitchDefaults INSTANCE;
+ }
+
public final class SwitchKt {
method @androidx.compose.runtime.Composable public static void Switch(boolean checked, androidx.glance.action.Action? onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function0<kotlin.Unit> onCheckedChange, optional androidx.glance.GlanceModifier modifier, optional String text, optional androidx.glance.text.TextStyle? style, optional androidx.glance.appwidget.SwitchColors colors, optional int maxLines);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors(androidx.glance.unit.ColorProvider checkedThumbColor, androidx.glance.unit.ColorProvider uncheckedThumbColor, androidx.glance.unit.ColorProvider checkedTrackColor, androidx.glance.unit.ColorProvider uncheckedTrackColor);
- method @androidx.compose.runtime.Composable public static androidx.glance.appwidget.SwitchColors switchColors();
}
}
diff --git a/glance/glance-appwidget/build.gradle b/glance/glance-appwidget/build.gradle
index b098ddc..3eaf94a 100644
--- a/glance/glance-appwidget/build.gradle
+++ b/glance/glance-appwidget/build.gradle
@@ -86,6 +86,8 @@
androidTestImplementation(libs.testRunner)
androidTestImplementation(libs.truth)
androidTestImplementation(libs.kotlinReflect)
+
+ samples(projectOrArtifact(":glance:glance-appwidget:glance-appwidget-samples"))
}
android {
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
index e6fbcbf..597ba89 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
@@ -27,18 +27,18 @@
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.appwidget.CheckBox
+import androidx.glance.appwidget.CheckboxDefaults
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.RadioButton
+import androidx.glance.appwidget.RadioButtonDefaults
import androidx.glance.appwidget.SizeMode
import androidx.glance.appwidget.Switch
+import androidx.glance.appwidget.SwitchDefaults
import androidx.glance.appwidget.appWidgetBackground
-import androidx.glance.appwidget.checkBoxColors
import androidx.glance.appwidget.cornerRadius
-import androidx.glance.appwidget.radioButtonColors
import androidx.glance.appwidget.selectableGroup
import androidx.glance.appwidget.provideContent
-import androidx.glance.appwidget.switchColors
import androidx.glance.background
import androidx.glance.color.ColorProvider
import androidx.glance.layout.Alignment
@@ -94,7 +94,7 @@
text = "Checkbox 2",
style = textStyle,
modifier = fillModifier,
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = ColorProvider(day = Color.Red, night = Color.Cyan),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Magenta)
)
@@ -108,7 +108,7 @@
checked = switch1Checked,
onCheckedChange = { switch1Checked = !switch1Checked },
text = "Switch 1",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(day = Color.Red, night = Color.Cyan),
uncheckedThumbColor = ColorProvider(day = Color.Green, night = Color.Magenta),
checkedTrackColor = ColorProvider(day = Color.Blue, night = Color.Yellow),
@@ -127,7 +127,7 @@
checked = radioChecked == 0,
onClick = { radioChecked = 0 },
text = "Radio 1",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Red, night = Color.Cyan),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Magenta)
),
@@ -136,7 +136,7 @@
checked = radioChecked == 1,
onClick = { radioChecked = 1 },
text = "Radio 2",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Cyan, night = Color.Yellow),
uncheckedColor = ColorProvider(day = Color.Red, night = Color.Blue)
),
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt
index fe9dbc3..c4cdd7a 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/DefaultStateAppWidget.kt
@@ -1,7 +1,6 @@
package androidx.glance.appwidget.demos
import android.content.Context
-import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.glance.Button
@@ -14,6 +13,7 @@
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
import androidx.glance.appwidget.appWidgetBackground
+import androidx.glance.appwidget.provideContent
import androidx.glance.appwidget.state.updateAppWidgetState
import androidx.glance.background
import androidx.glance.currentState
@@ -35,9 +35,7 @@
// the +/- clicks values.
class DefaultStateAppWidget : GlanceAppWidget() {
- @Composable
- @Deprecated("")
- override fun Content() {
+ override suspend fun provideGlance(context: Context, id: GlanceId) = provideContent {
// Get the current stored value for the given Key.
val count = currentState(CountClicksKey) ?: 0
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
index cdea0ef..aaf9c38 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ResponsiveAppWidget.kt
@@ -24,7 +24,7 @@
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.LocalContext
@@ -157,7 +157,7 @@
Button(
text = text,
modifier = GlanceModifier.fillMaxSize().padding(8.dp).background(color),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(color),
contentColor = ColorProvider(Color.White)
),
diff --git a/glance/glance-appwidget/samples/build.gradle b/glance/glance-appwidget/samples/build.gradle
new file mode 100644
index 0000000..e5279ee
--- /dev/null
+++ b/glance/glance-appwidget/samples/build.gradle
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.LibraryType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+ id("AndroidXPlugin")
+ id("com.android.library")
+ id("AndroidXComposePlugin")
+ id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+
+ implementation(libs.kotlinStdlib)
+ implementation("androidx.core:core:1.5.0")
+
+ compileOnly(project(":annotation:annotation-sampled"))
+
+ implementation(project(":glance:glance"))
+ implementation(project(":glance:glance-appwidget"))
+}
+
+androidx {
+ name = "Glance AppWidget Classes Samples"
+ type = LibraryType.SAMPLES
+ inceptionYear = "2023"
+ description = "Contains the sample code for the Glance AppWidget Classes Samples"
+}
+
+android {
+ namespace "androidx.glance.appwidget.samples"
+}
diff --git a/glance/glance-appwidget/samples/src/main/java/androidx/glance/appwidget/samples/GlanceAppWidgetSamples.kt b/glance/glance-appwidget/samples/src/main/java/androidx/glance/appwidget/samples/GlanceAppWidgetSamples.kt
new file mode 100644
index 0000000..43fec19
--- /dev/null
+++ b/glance/glance-appwidget/samples/src/main/java/androidx/glance/appwidget/samples/GlanceAppWidgetSamples.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.appwidget.samples
+
+import android.content.Context
+import androidx.annotation.Sampled
+import androidx.glance.GlanceId
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.provideContent
+import androidx.glance.text.Text
+
+@Sampled
+suspend fun GlanceAppWidget.provideGlanceSample(
+ @Suppress("UNUSED_PARAMETER") context: Context,
+ @Suppress("UNUSED_PARAMETER") id: GlanceId,
+) {
+ // Load data needed to render the AppWidget.
+ provideContent {
+ // create your AppWidget here
+ Text("Hello World")
+ }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
index b0897e3..3fcfbdd 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
@@ -24,7 +24,7 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
import androidx.glance.GlanceModifier
import androidx.glance.Image
import androidx.glance.ImageProvider
@@ -252,7 +252,7 @@
"Start",
onClick = actionStartActivity<Activity>(),
modifier = GlanceModifier.defaultWeight().fillMaxHeight(),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(Color.Transparent),
contentColor = ColorProvider(Color.DarkGray)
),
@@ -262,7 +262,7 @@
"End",
onClick = actionStartActivity<Activity>(),
modifier = GlanceModifier.defaultWeight().fillMaxHeight(),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(Color.Transparent),
contentColor = ColorProvider(Color.DarkGray)
),
@@ -656,7 +656,7 @@
Button(
"Button with textAlign = Start",
onClick = actionStartActivity<Activity>(),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(day = buttonBgColors[0], night = buttonBgColors[1]),
contentColor = ColorProvider(day = buttonTextColors[0], night = buttonTextColors[1])
),
@@ -667,7 +667,7 @@
"Button with textAlign = Center and padding (30dp, 30dp)",
onClick = actionStartActivity<Activity>(),
modifier = GlanceModifier.padding(horizontal = 30.dp, vertical = 30.dp),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(day = buttonBgColors[0], night = buttonBgColors[1]),
contentColor = ColorProvider(day = buttonTextColors[0], night = buttonTextColors[1])
),
@@ -677,7 +677,7 @@
Button(
"Button with textAlign = End",
onClick = actionStartActivity<Activity>(),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(day = buttonBgColors[0], night = buttonBgColors[1]),
contentColor = ColorProvider(day = buttonTextColors[0], night = buttonTextColors[1])
),
@@ -699,7 +699,7 @@
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Normal,
),
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = ColorProvider(day = Color.Magenta, night = Color.Yellow),
uncheckedColor = ColorProvider(day = Color.Black, night = Color.Gray)
)
@@ -715,7 +715,7 @@
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Italic,
),
- colors = checkBoxColors(checkedColor = Color.Red, uncheckedColor = Color.Green)
+ colors = CheckboxDefaults.colors(checkedColor = Color.Red, uncheckedColor = Color.Green)
)
}
}
@@ -732,7 +732,7 @@
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Normal,
),
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedThumbColor = ColorProvider(Color.Magenta),
checkedTrackColor = ColorProvider(day = Color.Green, night = Color.Yellow),
@@ -750,7 +750,7 @@
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Italic,
),
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(Color.Blue),
uncheckedThumbColor = ColorProvider(day = Color.Magenta, night = Color.Cyan),
checkedTrackColor = ColorProvider(Color.Blue),
@@ -775,7 +775,7 @@
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Normal,
),
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Magenta, night = Color.Yellow),
uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Magenta)
)
@@ -791,7 +791,10 @@
fontWeight = FontWeight.Medium,
fontStyle = FontStyle.Italic,
),
- colors = radioButtonColors(checkedColor = Color.Red, uncheckedColor = Color.Green)
+ colors = RadioButtonDefaults.colors(
+ checkedColor = Color.Red,
+ uncheckedColor = Color.Green
+ )
)
}
}
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
index 448dbf1..7ba78d1 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt
@@ -51,7 +51,7 @@
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.Image
@@ -443,7 +443,7 @@
Button(
text = "Button",
onClick = actionStartActivity<Activity>(),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(Color.Transparent),
contentColor = ColorProvider(Color.DarkGray)
),
@@ -470,7 +470,7 @@
Button(
text = "Button",
onClick = actionStartActivity<Activity>(),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(Color.Transparent),
contentColor = ColorProvider(Color.DarkGray)
),
@@ -887,7 +887,7 @@
fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Normal,
),
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(
day = Color.Blue,
night = Color.Red
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt
index bc88b30..3b4719e 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CheckBox.kt
@@ -44,59 +44,6 @@
) : CheckBoxColors()
/**
- * [checkBoxColors] that uses [checkedColor] or [uncheckedColor] depending ons the checked state of the
- * CheckBox.
- *
- * @param checkedColor the [Color] to use when the CheckBox is checked
- * @param uncheckedColor the [Color] to use when the CheckBox is not checked
- */
-@Composable
-fun checkBoxColors(checkedColor: Color, uncheckedColor: Color): CheckBoxColors =
- checkBoxColors(FixedColorProvider(checkedColor), FixedColorProvider(uncheckedColor))
-
-/**
- * [checkBoxColors] that uses [checkedColor] or [uncheckedColor] depending on the checked state of
- * the CheckBox.
- *
- * None of the [ColorProvider] parameters to this function can be created from resource ids. To use
- * resources to tint the check box color, use `CheckBoxColors(Int)` instead.
- *
- * @param checkedColor the [ColorProvider] to use when the check box is checked, or null to use the
- * default tint
- * @param uncheckedColor the [ColorProvider] to use when the check box is not checked, or null to
- * use the default tint
- */
-@Composable
-fun checkBoxColors(
- checkedColor: ColorProvider,
- uncheckedColor: ColorProvider
-): CheckBoxColors =
- CheckBoxColorsImpl(
- createCheckableColorProvider(
- source = "CheckBoxColors",
- checked = checkedColor,
- unchecked = uncheckedColor,
- )
- )
-
-@Composable
-fun checkBoxColors(): CheckBoxColors {
- val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
- // If using the m3 dynamic color theme, we need to create a color provider from xml
- // because resource backed ColorStateLists cannot be created programmatically
- ResourceCheckableColorProvider(R.color.glance_default_check_box)
- } else {
- createCheckableColorProvider(
- source = "CheckBoxColors",
- checked = GlanceTheme.colors.primary,
- unchecked = GlanceTheme.colors.onSurface
- )
- }
-
- return CheckBoxColorsImpl(colorProvider)
-}
-
-/**
* Adds a check box view to the glance view.
*
* @param checked whether the check box is checked
@@ -118,7 +65,7 @@
modifier: GlanceModifier = GlanceModifier,
text: String = "",
style: TextStyle? = null,
- colors: CheckBoxColors = checkBoxColors(),
+ colors: CheckBoxColors = CheckboxDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) = CheckBoxElement(checked, onCheckedChange, modifier, text, style, colors, maxLines)
@@ -141,7 +88,7 @@
modifier: GlanceModifier = GlanceModifier,
text: String = "",
style: TextStyle? = null,
- colors: CheckBoxColors = checkBoxColors(),
+ colors: CheckBoxColors = CheckboxDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) = CheckBoxElement(
checked,
@@ -160,7 +107,7 @@
modifier: GlanceModifier = GlanceModifier,
text: String = "",
style: TextStyle? = null,
- colors: CheckBoxColors = checkBoxColors(),
+ colors: CheckBoxColors = CheckboxDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) {
val finalModifier = if (onCheckedChange != null) {
@@ -181,6 +128,67 @@
)
}
+/**
+ * Contains the default values used by [CheckBox].
+ */
+object CheckboxDefaults {
+
+ /**
+ * @param checkedColor the [ColorProvider] to use when the check box is checked.
+ * @param uncheckedColor the [ColorProvider] to use when the check box is not checked.
+ * @return [CheckBoxColors] that uses [checkedColor] or [uncheckedColor] depending on the
+ * checked state of the CheckBox.
+ */
+ @Composable
+ fun colors(
+ checkedColor: ColorProvider,
+ uncheckedColor: ColorProvider
+ ): CheckBoxColors =
+ CheckBoxColorsImpl(
+ createCheckableColorProvider(
+ source = "CheckBoxColors",
+ checked = checkedColor,
+ unchecked = uncheckedColor,
+ )
+ )
+
+ /**
+ * @param checkedColor the [Color] to use when the check box is checked.
+ * @param uncheckedColor the [Color] to use when the check box is not checked.
+ * @return [CheckBoxColors] that uses [checkedColor] or [uncheckedColor] depending on the
+ * checked state of the CheckBox.
+ */
+ @Composable
+ fun colors(
+ checkedColor: Color,
+ uncheckedColor: Color
+ ): CheckBoxColors = CheckboxDefaults.colors(
+ checkedColor = FixedColorProvider(checkedColor),
+ uncheckedColor = FixedColorProvider(uncheckedColor)
+ )
+
+ /**
+ * Creates a default [CheckBoxColors].
+ * @return default [CheckBoxColors].
+ */
+ @Composable
+ fun colors(): CheckBoxColors {
+ val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
+ // If using the m3 dynamic color theme, we need to create a color provider from xml
+ // because resource backed ColorStateLists cannot be created programmatically
+ ResourceCheckableColorProvider(R.color.glance_default_check_box)
+ } else {
+ createCheckableColorProvider(
+ source = "CheckBoxColors",
+ checked = GlanceTheme.colors.primary,
+ unchecked = GlanceTheme.colors.onSurface
+ )
+ }
+
+ return CheckBoxColorsImpl(colorProvider)
+ }
+}
+
internal class EmittableCheckBox(
var colors: CheckBoxColors
) : Emittable {
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
index 8fafe34..2638da4 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
@@ -50,35 +50,19 @@
internal val errorUiLayout: Int = R.layout.glance_error_layout,
) {
private val sessionManager: SessionManager = GlanceSessionManager
+
/**
* Override this function to provide the Glance Composable.
*
* This is a good place to load any data needed to render the Composable. Use
- * [provideContent] to provide the Composable once it is ready.
+ * [provideContent] to provide the Composable once the data is ready.
+ *
+ * @sample androidx.glance.appwidget.samples.provideGlanceSample
*/
- open suspend fun provideGlance(
+ abstract suspend fun provideGlance(
context: Context,
id: GlanceId,
- ) {
- provideContent { @Suppress("DEPRECATION") Content() }
- }
-
- /**
- * Provide the Glance Composable.
- */
- @Composable
- @GlanceComposable
- @Deprecated(
- message = "Override provideGlance to provide the Composable.",
- replaceWith = ReplaceWith(
- "override suspend fun provideGlance(context: Context, id: GlanceId) {" +
- " provideContent { /** Composable content **/ }" +
- "}",
- "androidx.glance.appwidget.provideContent",
- ),
- level = DeprecationLevel.WARNING,
)
- open fun Content() {}
/**
* Defines the handling of sizes.
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt
index 48bafbc..4db3e21 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RadioButton.kt
@@ -36,55 +36,6 @@
/** Set of colors to apply to a RadioButton depending on the checked state. */
class RadioButtonColors internal constructor(internal val radio: CheckableColorProvider)
-/**
- * RadioButtonColors to tint the drawable of the [RadioButton] according to the checked state.
- *
- * None of the [ColorProvider] parameters to this function can be created from resource ids. To use
- * resources to tint the switch color, use `RadioButtonColors(Int, Int)` instead.
- *
- * @param checkedColor the tint to apply to the radio button when it is checked, or null
- * to use the default tint.
- * @param uncheckedColor the tint to apply to the radio button when it is not checked,
- * or null to use the default tint.
- */
-fun radioButtonColors(
- checkedColor: ColorProvider,
- uncheckedColor: ColorProvider,
-): RadioButtonColors {
- return RadioButtonColors(
- radio = createCheckableColorProvider(
- source = "RadioButtonColors", checked = checkedColor, unchecked = uncheckedColor
- )
- )
-}
-
-/**
- * [radioButtonColors] that uses [checkedColor] or [uncheckedColor] depending on the checked state
- * of the RadioButton.
- *
- * @param checkedColor the [Color] to use when the RadioButton is checked
- * @param uncheckedColor the [Color] to use when the RadioButton is not checked
- */
-fun radioButtonColors(checkedColor: Color, uncheckedColor: Color): RadioButtonColors =
- radioButtonColors(FixedColorProvider(checkedColor), FixedColorProvider(uncheckedColor))
-
-@Composable
-fun radioButtonColors(): RadioButtonColors {
- val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
- // If using the m3 dynamic color theme, we need to create a color provider from xml
- // because resource backed ColorStateLists cannot be created programmatically
- ResourceCheckableColorProvider(R.color.glance_default_radio_button)
- } else {
- createCheckableColorProvider(
- source = "CheckBoxColors",
- checked = GlanceTheme.colors.primary,
- unchecked = GlanceTheme.colors.onSurfaceVariant
- )
- }
-
- return RadioButtonColors(colorProvider)
-}
-
internal class EmittableRadioButton(
var colors: RadioButtonColors
) : Emittable {
@@ -141,7 +92,7 @@
enabled: Boolean = true,
text: String = "",
style: TextStyle? = null,
- colors: RadioButtonColors = radioButtonColors(),
+ colors: RadioButtonColors = RadioButtonDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) = RadioButtonElement(checked, onClick, modifier, enabled, text, style, colors, maxLines)
@@ -170,7 +121,7 @@
enabled: Boolean = true,
text: String = "",
style: TextStyle? = null,
- colors: RadioButtonColors = radioButtonColors(),
+ colors: RadioButtonColors = RadioButtonDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) = RadioButtonElement(
checked,
@@ -183,6 +134,65 @@
maxLines
)
+/**
+ * Contains the default values used by [RadioButton].
+ */
+object RadioButtonDefaults {
+ /**
+ * Creates a [RadioButtonColors] using [ColorProvider]s.
+ * @param checkedColor the tint to apply to the radio button when it is checked.
+ * @param uncheckedColor the tint to apply to the radio button when it is not checked.
+ * @return [RadioButtonColors] to tint the drawable of the [RadioButton] according to
+ * the checked state.
+ */
+ fun colors(
+ checkedColor: ColorProvider,
+ uncheckedColor: ColorProvider,
+ ): RadioButtonColors {
+ return RadioButtonColors(
+ radio = createCheckableColorProvider(
+ source = "RadioButtonColors", checked = checkedColor, unchecked = uncheckedColor
+ )
+ )
+ }
+
+ /**
+ * Creates a [RadioButtonColors] using [FixedColorProvider]s for the given colors.
+ * @param checkedColor the [Color] to use when the RadioButton is checked
+ * @param uncheckedColor the [Color] to use when the RadioButton is not checked
+ * @return [RadioButtonColors] to tint the drawable of the [RadioButton] according to
+ * the checked state.
+ */
+ fun colors(
+ checkedColor: Color,
+ uncheckedColor: Color
+ ): RadioButtonColors = colors(
+ checkedColor = FixedColorProvider(checkedColor),
+ uncheckedColor = FixedColorProvider(uncheckedColor)
+ )
+
+ /**
+ * Creates a default [RadioButtonColors]
+ * @return default [RadioButtonColors].
+ */
+ @Composable
+ fun colors(): RadioButtonColors {
+ val colorProvider = if (GlanceTheme.colors == DynamicThemeColorProviders) {
+ // If using the m3 dynamic color theme, we need to create a color provider from xml
+ // because resource backed ColorStateLists cannot be created programmatically
+ ResourceCheckableColorProvider(R.color.glance_default_radio_button)
+ } else {
+ createCheckableColorProvider(
+ source = "CheckBoxColors",
+ checked = GlanceTheme.colors.primary,
+ unchecked = GlanceTheme.colors.onSurfaceVariant
+ )
+ }
+
+ return RadioButtonColors(colorProvider)
+ }
+}
+
@Composable
private fun RadioButtonElement(
checked: Boolean,
@@ -191,7 +201,7 @@
enabled: Boolean = true,
text: String = "",
style: TextStyle? = null,
- colors: RadioButtonColors = radioButtonColors(),
+ colors: RadioButtonColors = RadioButtonDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) {
val finalModifier = if (enabled && onClick != null) modifier.clickable(onClick) else modifier
@@ -205,6 +215,7 @@
this.set(maxLines) { this.maxLines = it }
})
}
+
/**
* Use this modifier to group a list of RadioButtons together for accessibility purposes.
*
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt
index 4097244..06a9168 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Switch.kt
@@ -44,57 +44,6 @@
) : SwitchColors()
/**
- * SwitchColors to tint the thumb and track of the [Switch] according to the checked state.
- *
- * None of the [ColorProvider] parameters to this function can be created from resource ids.
- *
- * @param checkedThumbColor the tint to apply to the thumb of the switch when it is checked
- * @param uncheckedThumbColor the tint to apply to the thumb of the switch when it is not checked
- * @param checkedTrackColor the tint to apply to the track of the switch when it is checked
- * @param uncheckedTrackColor the tint to apply to the track of the switch when it is not checked
- */
-@Composable
-fun switchColors(
- checkedThumbColor: ColorProvider,
- uncheckedThumbColor: ColorProvider,
- checkedTrackColor: ColorProvider,
- uncheckedTrackColor: ColorProvider,
-): SwitchColors {
- return SwitchColorsImpl(
- thumb = createCheckableColorProvider(
- source = "SwitchColors",
- checked = checkedThumbColor,
- unchecked = uncheckedThumbColor,
- ),
- track = createCheckableColorProvider(
- source = "SwitchColors",
- checked = checkedTrackColor,
- unchecked = uncheckedTrackColor,
- )
- )
-}
-
-/**
- * Create a default set of SwitchColors.
- */
-@Composable
-fun switchColors(): SwitchColors {
- return if (GlanceTheme.colors == DynamicThemeColorProviders) {
- SwitchColorsImpl(
- thumb = ResourceCheckableColorProvider(R.color.glance_default_switch_thumb),
- track = ResourceCheckableColorProvider(R.color.glance_default_switch_track)
- )
- } else {
- switchColors(
- checkedThumbColor = GlanceTheme.colors.onPrimary,
- uncheckedThumbColor = GlanceTheme.colors.outline,
- checkedTrackColor = GlanceTheme.colors.primary,
- uncheckedTrackColor = GlanceTheme.colors.surfaceVariant,
- )
- }
-}
-
-/**
* Adds a switch view to the glance view.
*
* @param checked whether the switch is checked
@@ -116,7 +65,7 @@
modifier: GlanceModifier = GlanceModifier,
text: String = "",
style: TextStyle? = null,
- colors: SwitchColors = switchColors(),
+ colors: SwitchColors = SwitchDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) = SwitchElement(checked, onCheckedChange, modifier, text, style, colors, maxLines)
@@ -139,7 +88,7 @@
modifier: GlanceModifier = GlanceModifier,
text: String = "",
style: TextStyle? = null,
- colors: SwitchColors = switchColors(),
+ colors: SwitchColors = SwitchDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) = SwitchElement(
checked,
@@ -151,6 +100,65 @@
maxLines
)
+/**
+ * Contains the default values used by [Switch].
+ */
+object SwitchDefaults {
+
+ /**
+ * SwitchColors to tint the thumb and track of the [Switch] according to the checked state.
+ *
+ * @param checkedThumbColor the tint to apply to the thumb of the switch when it is checked
+ * @param uncheckedThumbColor the tint to apply to the thumb of the switch when it is not
+ * checked
+ * @param checkedTrackColor the tint to apply to the track of the switch when it is checked
+ * @param uncheckedTrackColor the tint to apply to the track of the switch when it is not
+ * checked
+ */
+ @Composable
+ fun colors(
+ checkedThumbColor: ColorProvider,
+ uncheckedThumbColor: ColorProvider,
+ checkedTrackColor: ColorProvider,
+ uncheckedTrackColor: ColorProvider,
+ ): SwitchColors {
+ return SwitchColorsImpl(
+ thumb = createCheckableColorProvider(
+ source = "SwitchColors",
+ checked = checkedThumbColor,
+ unchecked = uncheckedThumbColor,
+ ),
+ track = createCheckableColorProvider(
+ source = "SwitchColors",
+ checked = checkedTrackColor,
+ unchecked = uncheckedTrackColor,
+ )
+ )
+ }
+
+ /**
+ *
+ * SwitchColors to tint the thumb and track of the [Switch] according to the checked state.
+ * @return a default set of [SwitchColors].
+ */
+ @Composable
+ fun colors(): SwitchColors {
+ return if (GlanceTheme.colors == DynamicThemeColorProviders) {
+ SwitchColorsImpl(
+ thumb = ResourceCheckableColorProvider(R.color.glance_default_switch_thumb),
+ track = ResourceCheckableColorProvider(R.color.glance_default_switch_track)
+ )
+ } else {
+ colors(
+ checkedThumbColor = GlanceTheme.colors.onPrimary,
+ uncheckedThumbColor = GlanceTheme.colors.outline,
+ checkedTrackColor = GlanceTheme.colors.primary,
+ uncheckedTrackColor = GlanceTheme.colors.surfaceVariant,
+ )
+ }
+ }
+}
+
@Composable
private fun SwitchElement(
checked: Boolean,
@@ -158,7 +166,7 @@
modifier: GlanceModifier = GlanceModifier,
text: String = "",
style: TextStyle? = null,
- colors: SwitchColors = switchColors(),
+ colors: SwitchColors = SwitchDefaults.colors(),
maxLines: Int = Int.MAX_VALUE,
) {
val finalModifier = if (onCheckedChange != null) {
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt
index 1923a54..eb4b190 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/CheckBoxBackportTranslatorTest.kt
@@ -23,7 +23,7 @@
import androidx.compose.ui.graphics.Color
import androidx.glance.GlanceModifier
import androidx.glance.appwidget.CheckBox
-import androidx.glance.appwidget.checkBoxColors
+import androidx.glance.appwidget.CheckboxDefaults
import androidx.glance.appwidget.ImageViewSubject.Companion.assertThat
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
@@ -69,7 +69,10 @@
checked = false,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(checkedColor = Color.Red, uncheckedColor = Color.Blue)
+ colors = CheckboxDefaults.colors(
+ checkedColor = Color.Red,
+ uncheckedColor = Color.Blue
+ )
)
}
@@ -85,7 +88,10 @@
checked = true,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(checkedColor = Color.Red, uncheckedColor = Color.Blue)
+ colors = CheckboxDefaults.colors(
+ checkedColor = Color.Red,
+ uncheckedColor = Color.Blue
+ )
)
}
@@ -101,7 +107,7 @@
checked = false,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
)
@@ -120,7 +126,7 @@
checked = false,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
)
@@ -139,7 +145,7 @@
checked = true,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
)
@@ -158,7 +164,7 @@
checked = true,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = ColorProvider(day = Color.Red, night = Color.Blue),
uncheckedColor = ColorProvider(day = Color.Yellow, night = Color.Green)
)
@@ -177,7 +183,7 @@
checked = true,
onCheckedChange = null,
text = "Check",
- colors = checkBoxColors(
+ colors = CheckboxDefaults.colors(
checkedColor = FixedColorProvider(Color.Red),
uncheckedColor = FixedColorProvider(Color.Blue)
)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
index a0a6683..cddb9bd 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
@@ -25,7 +25,7 @@
import androidx.glance.GlanceModifier
import androidx.glance.appwidget.ImageViewSubject.Companion.assertThat
import androidx.glance.appwidget.RadioButton
-import androidx.glance.appwidget.radioButtonColors
+import androidx.glance.appwidget.RadioButtonDefaults
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
import androidx.glance.appwidget.applyRemoteViews
@@ -72,7 +72,7 @@
checked = false,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(Color.Blue),
uncheckedColor = ColorProvider(Color.Red),
)
@@ -90,7 +90,7 @@
checked = true,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(Color.Blue),
uncheckedColor = ColorProvider(Color.Red),
)
@@ -108,7 +108,7 @@
checked = false,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
)
@@ -126,7 +126,7 @@
checked = false,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
)
@@ -144,7 +144,7 @@
checked = true,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
)
@@ -162,7 +162,7 @@
checked = true,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
)
@@ -180,7 +180,7 @@
checked = false,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
)
@@ -198,7 +198,7 @@
checked = true,
onClick = null,
text = "RadioButton",
- colors = radioButtonColors(
+ colors = RadioButtonDefaults.colors(
checkedColor = ColorProvider(day = Color.Blue, night = Color.Red),
uncheckedColor = ColorProvider(day = Color.Green, night = Color.Yellow),
)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
index d4ba832..ec11aab 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
@@ -30,7 +30,7 @@
import androidx.glance.appwidget.configurationContext
import androidx.glance.appwidget.findView
import androidx.glance.appwidget.runAndTranslate
-import androidx.glance.appwidget.switchColors
+import androidx.glance.appwidget.SwitchDefaults
import androidx.glance.color.ColorProvider
import androidx.glance.semantics.contentDescription
import androidx.glance.semantics.semantics
@@ -70,7 +70,7 @@
checked = false,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(Color.Blue),
uncheckedThumbColor = ColorProvider(Color.Red),
checkedTrackColor = ColorProvider(Color.Green),
@@ -91,7 +91,7 @@
checked = true,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(Color.Blue),
uncheckedThumbColor = ColorProvider(Color.Red),
checkedTrackColor = ColorProvider(Color.Green),
@@ -116,7 +116,7 @@
checked = false,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(otherColor),
uncheckedThumbColor = ColorProvider(day = thumbColor, night = otherColor),
checkedTrackColor = ColorProvider(otherColor),
@@ -141,7 +141,7 @@
checked = false,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(otherColor),
uncheckedThumbColor = ColorProvider(day = otherColor, night = thumbColor),
checkedTrackColor = ColorProvider(otherColor),
@@ -166,7 +166,7 @@
checked = true,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(day = thumbColor, night = otherColor),
uncheckedThumbColor = ColorProvider(day = otherColor, night = otherColor),
checkedTrackColor = ColorProvider(day = trackColor, night = otherColor),
@@ -191,7 +191,7 @@
checked = true,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(day = otherColor, night = thumbColor),
uncheckedThumbColor = ColorProvider(otherColor),
checkedTrackColor = ColorProvider(day = otherColor, night = trackColor),
@@ -212,7 +212,7 @@
checked = false,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(Color.Magenta),
uncheckedThumbColor = ColorProvider(Color.Red),
checkedTrackColor = ColorProvider(Color.Magenta),
@@ -233,7 +233,7 @@
checked = true,
onCheckedChange = null,
text = "Switch",
- colors = switchColors(
+ colors = SwitchDefaults.colors(
checkedThumbColor = ColorProvider(Color.Red),
uncheckedThumbColor = ColorProvider(Color.Magenta),
checkedTrackColor = ColorProvider(Color.Blue),
diff --git a/glance/glance-wear-tiles/api/current.txt b/glance/glance-wear-tiles/api/current.txt
index c693cbc..fe52a64 100644
--- a/glance/glance-wear-tiles/api/current.txt
+++ b/glance/glance-wear-tiles/api/current.txt
@@ -87,8 +87,8 @@
ctor public CombinedGlanceCurvedModifier(androidx.glance.wear.tiles.curved.GlanceCurvedModifier outer, androidx.glance.wear.tiles.curved.GlanceCurvedModifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
@androidx.glance.wear.tiles.curved.CurvedScopeMarker public interface CurvedChildScope {
@@ -123,8 +123,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceCurvedModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
method public default infix androidx.glance.wear.tiles.curved.GlanceCurvedModifier then(androidx.glance.wear.tiles.curved.GlanceCurvedModifier other);
field public static final androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Companion Companion;
}
@@ -132,15 +132,15 @@
public static final class GlanceCurvedModifier.Companion implements androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceCurvedModifier.Element extends androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
public final class GlanceCurvedModifierKt {
diff --git a/glance/glance-wear-tiles/api/public_plus_experimental_current.txt b/glance/glance-wear-tiles/api/public_plus_experimental_current.txt
index ecc93bf..c7e2370 100644
--- a/glance/glance-wear-tiles/api/public_plus_experimental_current.txt
+++ b/glance/glance-wear-tiles/api/public_plus_experimental_current.txt
@@ -102,8 +102,8 @@
ctor public CombinedGlanceCurvedModifier(androidx.glance.wear.tiles.curved.GlanceCurvedModifier outer, androidx.glance.wear.tiles.curved.GlanceCurvedModifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
@androidx.glance.wear.tiles.curved.CurvedScopeMarker public interface CurvedChildScope {
@@ -138,8 +138,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceCurvedModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
method public default infix androidx.glance.wear.tiles.curved.GlanceCurvedModifier then(androidx.glance.wear.tiles.curved.GlanceCurvedModifier other);
field public static final androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Companion Companion;
}
@@ -147,15 +147,15 @@
public static final class GlanceCurvedModifier.Companion implements androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceCurvedModifier.Element extends androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
public final class GlanceCurvedModifierKt {
diff --git a/glance/glance-wear-tiles/api/restricted_current.txt b/glance/glance-wear-tiles/api/restricted_current.txt
index c693cbc..fe52a64 100644
--- a/glance/glance-wear-tiles/api/restricted_current.txt
+++ b/glance/glance-wear-tiles/api/restricted_current.txt
@@ -87,8 +87,8 @@
ctor public CombinedGlanceCurvedModifier(androidx.glance.wear.tiles.curved.GlanceCurvedModifier outer, androidx.glance.wear.tiles.curved.GlanceCurvedModifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
@androidx.glance.wear.tiles.curved.CurvedScopeMarker public interface CurvedChildScope {
@@ -123,8 +123,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceCurvedModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
method public default infix androidx.glance.wear.tiles.curved.GlanceCurvedModifier then(androidx.glance.wear.tiles.curved.GlanceCurvedModifier other);
field public static final androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Companion Companion;
}
@@ -132,15 +132,15 @@
public static final class GlanceCurvedModifier.Companion implements androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceCurvedModifier.Element extends androidx.glance.wear.tiles.curved.GlanceCurvedModifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.wear.tiles.curved.GlanceCurvedModifier.Element,? super R,? extends R> operation);
}
public final class GlanceCurvedModifierKt {
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
index 68be983..b167405 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
@@ -26,7 +26,7 @@
import androidx.compose.ui.unit.sp
import androidx.core.graphics.drawable.toBitmap
import androidx.glance.Button
-import androidx.glance.ButtonColors
+import androidx.glance.ButtonDefaults
import androidx.glance.ColorFilter
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
@@ -723,7 +723,7 @@
"Hello World",
onClick = actionStartActivity(TestActivity::class.java),
modifier = GlanceModifier.padding(1.dp),
- colors = ButtonColors(
+ colors = ButtonDefaults.buttonColors(
backgroundColor = ColorProvider(Color.Black),
contentColor = ColorProvider(Color.Magenta)
),
diff --git a/glance/glance/api/current.txt b/glance/glance/api/current.txt
index a0498de..47d790f 100644
--- a/glance/glance/api/current.txt
+++ b/glance/glance/api/current.txt
@@ -9,13 +9,17 @@
}
public final class ButtonColors {
- ctor public ButtonColors(androidx.glance.unit.ColorProvider backgroundColor, androidx.glance.unit.ColorProvider contentColor);
method public androidx.glance.unit.ColorProvider getBackgroundColor();
method public androidx.glance.unit.ColorProvider getContentColor();
property public final androidx.glance.unit.ColorProvider backgroundColor;
property public final androidx.glance.unit.ColorProvider contentColor;
}
+ public final class ButtonDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+ field public static final androidx.glance.ButtonDefaults INSTANCE;
+ }
+
public final class ButtonKt {
method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
@@ -33,12 +37,12 @@
ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
public final class CompositionLocalsKt {
- method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState();
+ method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
@@ -59,8 +63,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
field public static final androidx.glance.GlanceModifier.Companion Companion;
}
@@ -68,15 +72,15 @@
public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
public final class GlanceTheme {
@@ -381,10 +385,10 @@
public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
ctor public SemanticsConfiguration();
- method public operator <T> T! get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+ method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
- method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
}
public final class SemanticsModifierKt {
@@ -405,12 +409,12 @@
public final class SemanticsPropertyKey<T> {
ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
method public String getName();
- method public T? merge(T? parentValue, T? childValue);
+ method public T? merge(T? parentValue, T childValue);
property public final String name;
}
public interface SemanticsPropertyReceiver {
- method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
}
}
@@ -519,9 +523,10 @@
}
public final class TextDefaults {
- method public androidx.glance.text.TextStyle defaultTextStyle();
method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+ method public androidx.glance.text.TextStyle getDefaultTextStyle();
property public final androidx.glance.unit.ColorProvider defaultTextColor;
+ property public final androidx.glance.text.TextStyle defaultTextStyle;
field public static final androidx.glance.text.TextDefaults INSTANCE;
}
diff --git a/glance/glance/api/public_plus_experimental_current.txt b/glance/glance/api/public_plus_experimental_current.txt
index a0498de..47d790f 100644
--- a/glance/glance/api/public_plus_experimental_current.txt
+++ b/glance/glance/api/public_plus_experimental_current.txt
@@ -9,13 +9,17 @@
}
public final class ButtonColors {
- ctor public ButtonColors(androidx.glance.unit.ColorProvider backgroundColor, androidx.glance.unit.ColorProvider contentColor);
method public androidx.glance.unit.ColorProvider getBackgroundColor();
method public androidx.glance.unit.ColorProvider getContentColor();
property public final androidx.glance.unit.ColorProvider backgroundColor;
property public final androidx.glance.unit.ColorProvider contentColor;
}
+ public final class ButtonDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+ field public static final androidx.glance.ButtonDefaults INSTANCE;
+ }
+
public final class ButtonKt {
method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
@@ -33,12 +37,12 @@
ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
public final class CompositionLocalsKt {
- method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState();
+ method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
@@ -59,8 +63,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
field public static final androidx.glance.GlanceModifier.Companion Companion;
}
@@ -68,15 +72,15 @@
public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
public final class GlanceTheme {
@@ -381,10 +385,10 @@
public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
ctor public SemanticsConfiguration();
- method public operator <T> T! get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+ method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
- method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
}
public final class SemanticsModifierKt {
@@ -405,12 +409,12 @@
public final class SemanticsPropertyKey<T> {
ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
method public String getName();
- method public T? merge(T? parentValue, T? childValue);
+ method public T? merge(T? parentValue, T childValue);
property public final String name;
}
public interface SemanticsPropertyReceiver {
- method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
}
}
@@ -519,9 +523,10 @@
}
public final class TextDefaults {
- method public androidx.glance.text.TextStyle defaultTextStyle();
method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+ method public androidx.glance.text.TextStyle getDefaultTextStyle();
property public final androidx.glance.unit.ColorProvider defaultTextColor;
+ property public final androidx.glance.text.TextStyle defaultTextStyle;
field public static final androidx.glance.text.TextDefaults INSTANCE;
}
diff --git a/glance/glance/api/restricted_current.txt b/glance/glance/api/restricted_current.txt
index a0498de..47d790f 100644
--- a/glance/glance/api/restricted_current.txt
+++ b/glance/glance/api/restricted_current.txt
@@ -9,13 +9,17 @@
}
public final class ButtonColors {
- ctor public ButtonColors(androidx.glance.unit.ColorProvider backgroundColor, androidx.glance.unit.ColorProvider contentColor);
method public androidx.glance.unit.ColorProvider getBackgroundColor();
method public androidx.glance.unit.ColorProvider getContentColor();
property public final androidx.glance.unit.ColorProvider backgroundColor;
property public final androidx.glance.unit.ColorProvider contentColor;
}
+ public final class ButtonDefaults {
+ method @androidx.compose.runtime.Composable public androidx.glance.ButtonColors buttonColors(optional androidx.glance.unit.ColorProvider backgroundColor, optional androidx.glance.unit.ColorProvider contentColor);
+ field public static final androidx.glance.ButtonDefaults INSTANCE;
+ }
+
public final class ButtonKt {
method @androidx.compose.runtime.Composable public static void Button(String text, androidx.glance.action.Action onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
method @androidx.compose.runtime.Composable public static void Button(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.glance.GlanceModifier modifier, optional boolean enabled, optional androidx.glance.text.TextStyle? style, optional androidx.glance.ButtonColors colors, optional int maxLines);
@@ -33,12 +37,12 @@
ctor public CombinedGlanceModifier(androidx.glance.GlanceModifier outer, androidx.glance.GlanceModifier inner);
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
public final class CompositionLocalsKt {
- method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState();
+ method @androidx.compose.runtime.Composable public static inline <reified T> T currentState();
method @androidx.compose.runtime.Composable public static inline <reified T> T? currentState(androidx.datastore.preferences.core.Preferences.Key<T> key);
method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.glance.GlanceId> getLocalGlanceId();
@@ -59,8 +63,8 @@
@androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface GlanceModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
method public default infix androidx.glance.GlanceModifier then(androidx.glance.GlanceModifier other);
field public static final androidx.glance.GlanceModifier.Companion Companion;
}
@@ -68,15 +72,15 @@
public static final class GlanceModifier.Companion implements androidx.glance.GlanceModifier {
method public boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GlanceModifier.Element extends androidx.glance.GlanceModifier {
method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.glance.GlanceModifier.Element,java.lang.Boolean> predicate);
- method public default <R> R! foldIn(R? initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
- method public default <R> R! foldOut(R? initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
+ method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.glance.GlanceModifier.Element,? extends R> operation);
+ method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.glance.GlanceModifier.Element,? super R,? extends R> operation);
}
public final class GlanceTheme {
@@ -381,10 +385,10 @@
public final class SemanticsConfiguration implements androidx.glance.semantics.SemanticsPropertyReceiver {
ctor public SemanticsConfiguration();
- method public operator <T> T! get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
+ method public operator <T> T get(androidx.glance.semantics.SemanticsPropertyKey<T> key);
method public <T> T? getOrElseNullable(androidx.glance.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
method public <T> T? getOrNull(androidx.glance.semantics.SemanticsPropertyKey<T> key);
- method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
}
public final class SemanticsModifierKt {
@@ -405,12 +409,12 @@
public final class SemanticsPropertyKey<T> {
ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
method public String getName();
- method public T? merge(T? parentValue, T? childValue);
+ method public T? merge(T? parentValue, T childValue);
property public final String name;
}
public interface SemanticsPropertyReceiver {
- method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T? value);
+ method public operator <T> void set(androidx.glance.semantics.SemanticsPropertyKey<T> key, T value);
}
}
@@ -519,9 +523,10 @@
}
public final class TextDefaults {
- method public androidx.glance.text.TextStyle defaultTextStyle();
method public androidx.glance.unit.ColorProvider getDefaultTextColor();
+ method public androidx.glance.text.TextStyle getDefaultTextStyle();
property public final androidx.glance.unit.ColorProvider defaultTextColor;
+ property public final androidx.glance.text.TextStyle defaultTextStyle;
field public static final androidx.glance.text.TextDefaults INSTANCE;
}
diff --git a/glance/glance/build.gradle b/glance/glance/build.gradle
index bb05696..b8fb797 100644
--- a/glance/glance/build.gradle
+++ b/glance/glance/build.gradle
@@ -63,6 +63,21 @@
testImplementation("androidx.room:room-runtime:2.4.3")
testImplementation("androidx.work:work-testing:2.7.1")
testImplementation("com.google.android.material:material:1.6.0")
+
+ androidTestImplementation('androidx.test:monitor:1.5.0')
+ androidTestImplementation('androidx.core:core-ktx:1.7.0')
+ androidTestImplementation("androidx.work:work-testing:2.7.1")
+ androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
+ androidTestImplementation(libs.kotlinCoroutinesTest)
+ androidTestImplementation(libs.kotlinTest)
+ androidTestImplementation(libs.testCore)
+ androidTestImplementation(libs.testExtJunit)
+ androidTestImplementation(libs.testExtJunitKtx)
+ androidTestImplementation(libs.testRules)
+ androidTestImplementation(libs.testRunner)
+ androidTestImplementation(libs.truth)
+ androidTestImplementation("androidx.lifecycle:lifecycle-livedata:2.5.1")
+ androidTestImplementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
}
android {
diff --git a/glance/glance/src/androidAndroidTest/AndroidManifest.xml b/glance/glance/src/androidAndroidTest/AndroidManifest.xml
new file mode 100644
index 0000000..b4af9e2
--- /dev/null
+++ b/glance/glance/src/androidAndroidTest/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+</manifest>
diff --git a/glance/glance/src/androidAndroidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt b/glance/glance/src/androidAndroidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
new file mode 100644
index 0000000..9db9374
--- /dev/null
+++ b/glance/glance/src/androidAndroidTest/kotlin/androidx/glance/session/GlanceSessionManagerTest.kt
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.session
+
+import android.content.Context
+import android.util.Log
+import androidx.compose.runtime.Composable
+import androidx.glance.EmittableWithChildren
+import androidx.glance.GlanceModifier
+import androidx.glance.session.SessionWorker.Companion.TimeoutExitReason
+import androidx.glance.text.EmittableText
+import androidx.glance.text.Text
+import androidx.lifecycle.asFlow
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.work.Configuration
+import androidx.work.ListenableWorker
+import androidx.work.WorkInfo
+import androidx.work.WorkInfo.State
+import androidx.work.WorkManager
+import androidx.work.WorkerFactory
+import androidx.work.WorkerParameters
+import androidx.work.testing.SynchronousExecutor
+import androidx.work.testing.WorkManagerTestInitHelper
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.ExperimentalTime
+import kotlin.time.measureTime
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.testTimeSource
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+
+@OptIn(ExperimentalStdlibApi::class, ExperimentalTime::class, ExperimentalCoroutinesApi::class)
+class GlanceSessionManagerTest {
+ private val context = InstrumentationRegistry.getInstrumentation().targetContext!!
+
+ private val testScope = TestScope()
+ private val testSession = TestSession()
+
+ private lateinit var workerState: StateFlow<List<WorkInfo>>
+ private val workerStateScope = CoroutineScope(Job())
+
+ private val additionalTime = 200.milliseconds
+ private val idleTimeout = 200.milliseconds
+ private val initialTimeout = 500.milliseconds
+ private val timeouts = TimeoutOptions(
+ additionalTime = additionalTime,
+ idleTimeout = idleTimeout,
+ initialTimeout = initialTimeout,
+ timeSource = { testScope.currentTime },
+ )
+
+ @Before
+ fun before() = runBlocking {
+ val config = Configuration.Builder()
+ .setMinimumLoggingLevel(Log.DEBUG)
+ .setExecutor(SynchronousExecutor())
+ .setWorkerFactory(object : WorkerFactory() {
+ override fun createWorker(
+ appContext: Context,
+ workerClassName: String,
+ workerParameters: WorkerParameters
+ ): ListenableWorker {
+ assertThat(workerClassName).isEqualTo(SessionWorker::class.qualifiedName)
+ return SessionWorker(
+ appContext,
+ workerParameters,
+ GlanceSessionManager,
+ timeouts,
+ testScope.coroutineContext[CoroutineDispatcher]!!,
+ )
+ }
+ })
+ .build()
+ WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
+ workerState = WorkManager.getInstance(context)
+ .getWorkInfosForUniqueWorkLiveData(testSession.key)
+ .asFlow()
+ .stateIn(workerStateScope)
+ }
+
+ @After
+ fun after() {
+ testScope.cancel()
+ workerStateScope.cancel()
+ WorkManager.getInstance(context).cancelAllWork()
+ }
+
+ @Test
+ fun startingSessionRunsComposition() = testScope.runTest {
+ startSession()
+
+ val text = assertIs<EmittableText>(testSession.uiTree.receive().children.single())
+ assertThat(text.text).isEqualTo("Hello World")
+
+ assertNotNull(GlanceSessionManager.getSession(testSession.key)).close()
+ waitForWorkerSuccess()
+ }
+
+ @Test
+ fun sessionInitialTimeout() = testScope.runTest {
+ startSession()
+
+ // Timeout starts after first successful composition
+ testSession.uiTree.receive()
+ val timeout = testTimeSource.measureTime {
+ waitForWorkerTimeout()
+ }
+ assertThat(timeout).isEqualTo(initialTimeout)
+ }
+
+ @Test
+ fun sessionDoesNotTimeoutBeforeFirstComposition() = testScope.runTest {
+ startSession()
+
+ // The session is not subject to a timeout before the composition has been processed
+ // successfully for the first time.
+ delay(initialTimeout * 5)
+ assertThat(GlanceSessionManager.isSessionRunning(context, testSession.key)).isTrue()
+
+ testSession.uiTree.receive()
+ val timeout = testTimeSource.measureTime {
+ waitForWorkerTimeout()
+ }
+ assertThat(timeout).isEqualTo(initialTimeout)
+ }
+
+ @Test
+ fun sessionAddsTimeOnExternalEvents() = testScope.runTest {
+ startSession()
+
+ // Timeout starts after first successful composition, and is incremented every time an event
+ // is received.
+ testSession.uiTree.receive()
+ val timeout = testTimeSource.measureTime {
+ delay(initialTimeout - 1.milliseconds)
+ testSession.sendEvent()
+ waitForWorkerTimeout()
+ }
+ assertThat(timeout).isEqualTo(initialTimeout + additionalTime)
+ }
+
+ @Test
+ fun sessionDoesNotAddTimeOnExternalEventsIfThereIsEnoughTimeLeft() = testScope.runTest {
+ startSession()
+
+ // Timeout starts after first successful composition. There is still enough time when events
+ // arrive, so the deadline will not be extended.
+ testSession.uiTree.receive()
+ val timeout = testTimeSource.measureTime {
+ repeat(5) { testSession.sendEvent() }
+ waitForWorkerTimeout()
+ }
+ assertThat(timeout).isEqualTo(initialTimeout)
+ }
+
+ private suspend fun startSession() {
+ GlanceSessionManager.startSession(context, testSession)
+ waitForWorkerStart()
+ assertThat(GlanceSessionManager.isSessionRunning(context, testSession.key)).isTrue()
+ }
+
+ private suspend fun waitForWorkerState(vararg state: State) = workerState.first {
+ it.singleOrNull()?.state in state
+ }.single()
+
+ private suspend fun waitForWorkerStart() = waitForWorkerState(State.RUNNING)
+ private suspend fun waitForWorkerSuccess() = waitForWorkerState(State.SUCCEEDED)
+ private suspend fun waitForWorkerTimeout() = waitForWorkerSuccess().also {
+ assertThat(it.outputData.getBoolean(TimeoutExitReason, false)).isTrue()
+ }
+}
+
+class TestSession : Session("session-123") {
+ val uiTree = Channel<EmittableWithChildren>(capacity = Channel.RENDEZVOUS)
+
+ suspend fun sendEvent() = sendEvent(Any())
+
+ override fun createRootEmittable(): EmittableWithChildren = RootEmittable()
+
+ override fun provideGlance(context: Context) = @Composable {
+ Text("Hello World")
+ }
+
+ override suspend fun processEmittableTree(
+ context: Context,
+ root: EmittableWithChildren
+ ): Boolean {
+ uiTree.send(root)
+ return true
+ }
+
+ override suspend fun processEvent(context: Context, event: Any) {
+ }
+
+ private class RootEmittable(
+ override var modifier: GlanceModifier = GlanceModifier
+ ) : EmittableWithChildren() {
+ override fun copy() = RootEmittable(modifier).also {
+ it.children.addAll(children)
+ }
+ }
+}
+
+private suspend fun <T> Flow<T?>.firstNotNull() = first { it != null }!!
\ No newline at end of file
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt
index 19116de..ddfb772 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/Button.kt
@@ -44,7 +44,7 @@
modifier: GlanceModifier = GlanceModifier,
enabled: Boolean = true,
style: TextStyle? = null,
- colors: ButtonColors = defaultButtonColors(),
+ colors: ButtonColors = ButtonDefaults.buttonColors(),
maxLines: Int = Int.MAX_VALUE,
) = ButtonElement(text, onClick, modifier, enabled, style, colors, maxLines)
@@ -67,7 +67,7 @@
modifier: GlanceModifier = GlanceModifier,
enabled: Boolean = true,
style: TextStyle? = null,
- colors: ButtonColors = defaultButtonColors(),
+ colors: ButtonColors = ButtonDefaults.buttonColors(),
maxLines: Int = Int.MAX_VALUE,
) = ButtonElement(text, action(block = onClick), modifier, enabled, style, colors, maxLines)
@@ -78,7 +78,7 @@
modifier: GlanceModifier = GlanceModifier,
enabled: Boolean = true,
style: TextStyle? = null,
- colors: ButtonColors = defaultButtonColors(),
+ colors: ButtonColors = ButtonDefaults.buttonColors(),
maxLines: Int = Int.MAX_VALUE,
) {
var finalModifier = if (enabled) modifier.clickable(onClick) else modifier
@@ -132,7 +132,10 @@
}
/** Represents the colors used to style a button, prefer this to using the modifier. */
-class ButtonColors(val backgroundColor: ColorProvider, val contentColor: ColorProvider) {
+class ButtonColors internal constructor(
+ val backgroundColor: ColorProvider,
+ val contentColor: ColorProvider
+) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
@@ -152,8 +155,23 @@
}
}
-@Composable
-internal fun defaultButtonColors() = ButtonColors(
- GlanceTheme.colors.primary,
- GlanceTheme.colors.onPrimary
-)
+/**
+ * Contains the default values used by [Button].
+ */
+object ButtonDefaults {
+ @Composable
+ /**
+ * Creates a [ButtonColors] that represents the default background and content colors used in
+ * a [Button].
+ *
+ * @param backgroundColor the background color of this [Button]
+ * @param contentColor the content color of this [Button]
+ */
+ fun buttonColors(
+ backgroundColor: ColorProvider = GlanceTheme.colors.primary,
+ contentColor: ColorProvider = GlanceTheme.colors.onPrimary
+ ) = ButtonColors(
+ backgroundColor = backgroundColor,
+ contentColor = contentColor
+ )
+}
\ No newline at end of file
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/session/IdleEventBroadcastReceiver.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/session/IdleEventBroadcastReceiver.kt
new file mode 100644
index 0000000..372f57c
--- /dev/null
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/session/IdleEventBroadcastReceiver.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.session
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Build
+import android.os.PowerManager
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+
+internal class IdleEventBroadcastReceiver(val onIdle: () -> Unit) : BroadcastReceiver() {
+ companion object {
+ val events = listOf(
+ PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED,
+ PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED,
+ PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED
+ )
+ val filter = IntentFilter().apply {
+ events.forEach { addAction(it) }
+ }
+ }
+
+ override fun onReceive(context: Context, intent: Intent) {
+ if (intent.action in events)
+ checkIdleStatus(context)
+ }
+
+ internal fun checkIdleStatus(context: Context) {
+ // Idle status is not available before Android M
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
+
+ val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+ var isIdle = Api23Impl.isIdle(pm)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ isIdle = isIdle || Api33Impl.isLightIdleOrLowPowerStandby(pm)
+ }
+ if (isIdle) onIdle()
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+private object Api33Impl {
+ @DoNotInline
+ fun isLightIdleOrLowPowerStandby(pm: PowerManager): Boolean {
+ return pm.isLowPowerStandbyEnabled || pm.isDeviceLightIdleMode
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.M)
+private object Api23Impl {
+ @DoNotInline
+ fun isIdle(pm: PowerManager): Boolean {
+ return pm.isDeviceIdleMode
+ }
+}
+
+/**
+ * Observe idle events while running [block]. If the device enters idle mode, run [onIdle].
+ */
+internal suspend fun <T> observeIdleEvents(
+ context: Context,
+ onIdle: suspend () -> Unit,
+ block: suspend () -> T,
+): T = coroutineScope {
+ val idleReceiver = IdleEventBroadcastReceiver { launch { onIdle() } }
+ context.registerReceiver(idleReceiver, IdleEventBroadcastReceiver.filter)
+ try {
+ idleReceiver.checkIdleStatus(context)
+ return@coroutineScope block()
+ } finally {
+ context.unregisterReceiver(idleReceiver)
+ }
+}
\ No newline at end of file
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt
index b09f015..e3cb1fa 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/session/SessionWorker.kt
@@ -18,20 +18,38 @@
import android.content.Context
import android.util.Log
-import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composition
import androidx.compose.runtime.Recomposer
import androidx.glance.Applier
import androidx.glance.EmittableWithChildren
import androidx.work.CoroutineWorker
+import androidx.work.Data
import androidx.work.WorkerParameters
+import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withTimeoutOrNull
+
+/**
+ * Options to configure [SessionWorker] timeouts.
+ * @property initialTimeout How long to wait after the first successful composition before timing
+ * out.
+ * @property additionalTime If an external event is received and there is less than [additionalTime]
+ * remaining, add [additionalTime] so that there is enough time to respond to the event.
+ * @property idleTimeout Timeout within [idleTimeout] if the system is in idle/light idle/low power
+ * standby mode.
+ * @property timeSource The time source for measuring progress towards timeouts.
+ */
+internal data class TimeoutOptions(
+ val initialTimeout: Duration = 45.seconds,
+ val additionalTime: Duration = 5.seconds,
+ val idleTimeout: Duration = 5.seconds,
+ val timeSource: TimeSource = TimeSource.Monotonic,
+)
/**
* [SessionWorker] handles composition for a particular Glanceable.
@@ -44,25 +62,44 @@
internal class SessionWorker(
appContext: Context,
params: WorkerParameters,
+ private val sessionManager: SessionManager = GlanceSessionManager,
+ private val timeouts: TimeoutOptions = TimeoutOptions(),
+ @Deprecated("Deprecated by super class, replacement in progress, see b/245353737")
+ override val coroutineContext: CoroutineDispatcher = Dispatchers.Main
) : CoroutineWorker(appContext, params) {
- @VisibleForTesting
- internal var sessionManager: SessionManager = GlanceSessionManager
+ // This constructor is required by WorkManager's default WorkerFactory.
+ constructor(appContext: Context, params: WorkerParameters) : this(
+ appContext,
+ params,
+ GlanceSessionManager,
+ )
companion object {
private const val TAG = "GlanceSessionWorker"
private const val DEBUG = false
- @VisibleForTesting
- internal val defaultTimeout = 45.seconds
+ internal const val TimeoutExitReason = "TIMEOUT_EXIT_REASON"
}
private val key = inputData.getString(sessionManager.keyParam)
- ?: error("SessionWorker must be started with a key")
+ ?: error("SessionWorker must be started with a key")
- @Deprecated("Deprecated by super class, replacement in progress, see b/245353737")
- override val coroutineContext = Dispatchers.Main
+ override suspend fun doWork() =
+ withTimerOrNull(timeouts.timeSource) {
+ observeIdleEvents(
+ applicationContext,
+ onIdle = {
+ startTimer(timeouts.idleTimeout)
+ if (DEBUG) Log.d(TAG, "Received idle event, session timeout $timeLeft")
+ }
+ ) {
+ work()
+ }
+ } ?: Result.success(Data.Builder().putBoolean(TimeoutExitReason, true).build())
- override suspend fun doWork(): Result = withTimeoutOrNull(defaultTimeout) {
- val session = sessionManager.getSession(key) ?: error("No session available for key $key")
+ private suspend fun TimerScope.work(): Result {
+ val session = sessionManager.getSession(key)
+ ?: error("No session available for key $key")
+
if (DEBUG) Log.d(TAG, "Setting up composition for ${session.key}")
val frameClock = InteractiveFrameClock(this)
val snapshotMonitor = launch { globalSnapshotMonitor() }
@@ -83,15 +120,21 @@
when (state) {
Recomposer.State.Idle -> {
// Only update the session when a change has actually occurred. The
- // Recomposer may sometimes wake up due to changes in other compositions.
- // Also update the session if we have not sent an initial tree yet.
+ // Recomposer may sometimes wake up due to changes in other
+ // compositions. Also update the session if we have not sent an initial
+ // tree yet.
if (recomposer.changeCount > lastRecomposeCount || !uiReady.value) {
if (DEBUG) Log.d(TAG, "UI tree updated (${session.key})")
val processed = session.processEmittableTree(
applicationContext,
root.copy() as EmittableWithChildren
)
- if (!uiReady.value && processed) uiReady.emit(true)
+ // If the UI has been processed for the first time, set uiReady to true
+ // and start the timeout.
+ if (!uiReady.value && processed) {
+ uiReady.emit(true)
+ startTimer(timeouts.initialTimeout)
+ }
}
lastRecomposeCount = recomposer.changeCount
}
@@ -100,11 +143,13 @@
}
}
}
-
// Wait until the Emittable tree has been processed at least once before receiving events.
uiReady.first { it }
session.receiveEvents(applicationContext) {
- if (DEBUG) Log.d(TAG, "processing event for ${session.key}")
+ // If time is running low, add time to make sure that we have time to respond to this
+ // event.
+ if (timeLeft < timeouts.additionalTime) addTime(timeouts.additionalTime)
+ if (DEBUG) Log.d(TAG, "processing event for ${session.key}; $timeLeft left")
launch { frameClock.startInteractive() }
}
@@ -113,6 +158,6 @@
snapshotMonitor.cancel()
recomposer.close()
recomposer.join()
- return@withTimeoutOrNull Result.success()
- } ?: Result.success()
+ return Result.success()
+ }
}
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/session/TimerScope.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/session/TimerScope.kt
new file mode 100644
index 0000000..fd3b317
--- /dev/null
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/session/TimerScope.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.session
+
+import java.util.concurrent.atomic.AtomicReference
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+internal class TimeoutCancellationException(
+ override val message: String,
+ internal val block: Int,
+) : CancellationException(message) {
+ override fun toString() = "TimeoutCancellationException($message, $block)"
+ override fun fillInStackTrace() = this
+}
+
+/**
+ * This interface is similar to [kotlin.time.TimeSource], which is still marked experimental.
+ */
+internal fun interface TimeSource {
+ /**
+ * Current time in milliseconds.
+ */
+ fun markNow(): Long
+
+ companion object {
+ val Monotonic = TimeSource { System.currentTimeMillis() }
+ }
+}
+
+/**
+ * TimerScope is a CoroutineScope that allows setting an adjustable timeout for all of the
+ * coroutines in the scope.
+ */
+internal interface TimerScope : CoroutineScope {
+ /**
+ * Amount of time left before this timer cancels the scope. This is not valid before
+ * [startTimer] is called.
+ */
+ val timeLeft: Duration
+
+ /**
+ * Start the timer with an [initialTimeout].
+ *
+ * Once the [initialTimeout] has passed, the scope is cancelled. If [startTimer] is called again
+ * while the timer is running, it will reset the timer if [initialTimeout] is less than
+ * [timeLeft]. If [initialTimeout] is larger than [timeLeft], the current timer is kept.
+ *
+ * In order to extend the deadline, call [addTime].
+ */
+ fun startTimer(initialTimeout: Duration)
+
+ /**
+ * Shift the deadline for this timer forward by [time].
+ */
+ fun addTime(time: Duration)
+}
+
+internal suspend fun <T> withTimer(
+ timeSource: TimeSource = TimeSource.Monotonic,
+ block: suspend TimerScope.() -> T,
+): T = coroutineScope {
+ val timerScope = this
+ val timerJob: AtomicReference<Job?> = AtomicReference(null)
+ coroutineScope {
+ val blockScope = object : TimerScope, CoroutineScope by this {
+ override val timeLeft: Duration
+ get() = (deadline.get()?.minus(timeSource.markNow()))?.milliseconds
+ ?: Duration.INFINITE
+ private val deadline: AtomicReference<Long?> = AtomicReference(null)
+
+ override fun addTime(time: Duration) {
+ deadline.update {
+ checkNotNull(it) { "Start the timer with startTimer before calling addTime" }
+ require(time.isPositive()) { "Cannot call addTime with a negative duration" }
+ it + time.inWholeMilliseconds
+ }
+ }
+
+ override fun startTimer(initialTimeout: Duration) {
+ if (initialTimeout.inWholeMilliseconds <= 0) {
+ timerScope.cancel(
+ TimeoutCancellationException("Timed out immediately", block.hashCode())
+ )
+ return
+ }
+ if (timeLeft < initialTimeout) return
+
+ deadline.set(timeSource.markNow() + initialTimeout.inWholeMilliseconds)
+ // Loop until the deadline is reached.
+ timerJob.getAndSet(
+ timerScope.launch {
+ while (deadline.get()!! > timeSource.markNow()) {
+ delay(timeLeft)
+ }
+ timerScope.cancel(
+ TimeoutCancellationException(
+ "Timed out of executing block.",
+ block.hashCode()
+ )
+ )
+ }
+ )?.cancel()
+ }
+ }
+ blockScope.block()
+ }.also {
+ timerJob.get()?.cancel()
+ }
+}
+
+internal suspend fun <T> withTimerOrNull(
+ timeSource: TimeSource = TimeSource.Monotonic,
+ block: suspend TimerScope.() -> T,
+): T? = try {
+ withTimer(timeSource, block)
+} catch (e: TimeoutCancellationException) {
+ // Return null if it's our exception, else propagate it upstream in case there are nested
+ // withTimers
+ if (e.block == block.hashCode()) null else throw e
+}
+
+// Update the value of the AtomicReference using the given updater function. Will throw an error
+// if unable to successfully set the value.
+private fun <T> AtomicReference<T>.update(updater: (T) -> T) {
+ while (true) {
+ get().let {
+ if (compareAndSet(it, updater(it))) return
+ }
+ }
+}
diff --git a/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt b/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt
index b079d59..ace0cfb 100644
--- a/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt
+++ b/glance/glance/src/androidMain/kotlin/androidx/glance/text/Text.kt
@@ -39,7 +39,7 @@
fun Text(
text: String,
modifier: GlanceModifier = GlanceModifier,
- style: TextStyle = defaultTextStyle(),
+ style: TextStyle = defaultTextStyle,
maxLines: Int = Int.MAX_VALUE,
) {
GlanceNode(
@@ -55,7 +55,7 @@
object TextDefaults {
val defaultTextColor = ColorProvider(Color.Black)
- fun defaultTextStyle(): TextStyle = TextStyle(color = defaultTextColor)
+ val defaultTextStyle: TextStyle = TextStyle(color = defaultTextColor)
}
/** @suppress */
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/IdleEventBroadcastReceiverTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/IdleEventBroadcastReceiverTest.kt
new file mode 100644
index 0000000..5d20c8f
--- /dev/null
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/IdleEventBroadcastReceiverTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.session
+
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import android.os.PowerManager
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicInteger
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.Shadows
+import org.robolectric.annotation.Config
+
+@RunWith(RobolectricTestRunner::class)
+class IdleEventBroadcastReceiverTest() {
+ private val receiver = IdleEventBroadcastReceiver { onIdleCalled.incrementAndGet() }
+ private val onIdleCalled = AtomicInteger(0)
+ private val context = ApplicationProvider.getApplicationContext<Context>()
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.M)
+ fun onReceive_idleModeChanged() {
+ val pm = Shadows.shadowOf(context.getSystemService(PowerManager::class.java))
+
+ pm.setIsDeviceIdleMode(false)
+ receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED))
+ assertThat(onIdleCalled.get()).isEqualTo(0)
+
+ pm.setIsDeviceIdleMode(true)
+ receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED))
+ assertThat(onIdleCalled.get()).isEqualTo(1)
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+ fun onReceive_lightIdleModeChanged() {
+ val pm = Shadows.shadowOf(context.getSystemService(PowerManager::class.java))
+
+ pm.setIsDeviceLightIdleMode(false)
+ receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED))
+ assertThat(onIdleCalled.get()).isEqualTo(0)
+
+ pm.setIsDeviceLightIdleMode(true)
+ receiver.onReceive(context, Intent(PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED))
+ assertThat(onIdleCalled.get()).isEqualTo(1)
+ }
+}
\ No newline at end of file
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
index ea5ebc6..43a1916 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/SessionWorkerTest.kt
@@ -29,6 +29,8 @@
import androidx.test.core.app.ApplicationProvider
import androidx.work.Data
import androidx.work.ListenableWorker.Result
+import androidx.work.WorkerFactory
+import androidx.work.WorkerParameters
import androidx.work.testing.TestListenableWorkerBuilder
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertIs
@@ -36,7 +38,6 @@
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -55,10 +56,14 @@
context = ApplicationProvider.getApplicationContext()
worker = TestListenableWorkerBuilder<SessionWorker>(context)
.setInputData(Data(mapOf(sessionManager.keyParam to SESSION_KEY)))
+ .setWorkerFactory(object : WorkerFactory() {
+ override fun createWorker(
+ appContext: Context,
+ workerClassName: String,
+ workerParameters: WorkerParameters
+ ) = SessionWorker(appContext, workerParameters, sessionManager)
+ })
.build()
- .also {
- it.sessionManager = sessionManager
- }
}
@Test
@@ -150,16 +155,6 @@
}
sessionManager.closeSession()
}
-
- @Test
- fun sessionWorkerTimeout() = runTest {
- launch {
- val result = worker.doWork()
- assertThat(result).isEqualTo(Result.success())
- }
- sessionManager.startSession(context)
- advanceTimeBy(SessionWorker.defaultTimeout.inWholeMilliseconds + 1)
- }
}
private const val SESSION_KEY = "123"
diff --git a/glance/glance/src/test/kotlin/androidx/glance/session/WithTimerTest.kt b/glance/glance/src/test/kotlin/androidx/glance/session/WithTimerTest.kt
new file mode 100644
index 0000000..8bafe94
--- /dev/null
+++ b/glance/glance/src/test/kotlin/androidx/glance/session/WithTimerTest.kt
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.session
+
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(RobolectricTestRunner::class)
+class WithTimerTest {
+ private val TestScope.timeSource
+ get() = TimeSource { currentTime }
+
+ @Test
+ fun completingNormallyThrowsNoException() = runTest {
+ val result = async {
+ withTimerOrNull(timeSource) {
+ startTimer(200.milliseconds)
+ delay(100.milliseconds)
+ Any()
+ }
+ }
+ assertThat(result.await()).isNotNull()
+ }
+
+ @Test
+ fun completingNormallyDoesNotCancelParentJob() = runTest {
+ val timerSuccess = Job()
+ val parentJob = launch {
+ withTimer(timeSource) {
+ startTimer(200.milliseconds)
+ delay(100.milliseconds)
+ }
+ timerSuccess.complete()
+ delay(Duration.INFINITE)
+ }
+ timerSuccess.join()
+ assertThat(timerSuccess.isCompleted).isTrue()
+ assertThat(parentJob.isActive).isTrue()
+ parentJob.cancel()
+ }
+
+ @Test
+ fun timeoutThrowsTimeoutCancellationException() = runTest {
+ var expected: TimeoutCancellationException? = null
+ try {
+ withTimer(timeSource) {
+ startTimer(200.milliseconds)
+ delay(1.seconds)
+ }
+ } catch (e: TimeoutCancellationException) {
+ expected = e
+ } finally {
+ assertThat(expected).isNotNull()
+ }
+ }
+
+ @Test
+ fun doesNotTimeoutBeforeStartTimer() = runTest {
+ var unexpected: TimeoutCancellationException? = null
+ try {
+ withTimer(timeSource) {
+ delay(30.days)
+ startTimer(200.milliseconds)
+ delay(100.milliseconds)
+ }
+ } catch (e: TimeoutCancellationException) {
+ unexpected = e
+ } finally {
+ assertThat(unexpected).isNull()
+ }
+ }
+
+ @Test
+ fun addTime() = runTest {
+ var unexpected: TimeoutCancellationException? = null
+ try {
+ withTimer(timeSource) {
+ startTimer(200.milliseconds)
+ delay(100)
+ assertThat(timeLeft).isEqualTo(100.milliseconds)
+ addTime(100.milliseconds)
+ assertThat(timeLeft).isEqualTo(200.milliseconds)
+ delay(199.milliseconds)
+ }
+ } catch (e: TimeoutCancellationException) {
+ unexpected = e
+ } finally {
+ assertThat(unexpected).isNull()
+ }
+ }
+
+ @Test
+ fun addTimeBeforeStartTimer() = runTest {
+ var expected: IllegalStateException? = null
+ try {
+ withTimer(timeSource) {
+ addTime(100.milliseconds)
+ }
+ } catch (e: IllegalStateException) {
+ expected = e
+ } finally {
+ assertThat(expected).isNotNull()
+ }
+ }
+
+ @Test
+ fun addNegativeDuration() = runTest {
+ var expected: IllegalArgumentException? = null
+ try {
+ withTimer(timeSource) {
+ startTimer(100.milliseconds)
+ addTime(-100.milliseconds)
+ }
+ } catch (e: IllegalArgumentException) {
+ expected = e
+ } finally {
+ assertThat(expected).isNotNull()
+ }
+ }
+
+ @Test
+ fun nestedWithTimerOrNull() = runTest {
+ val checkpoint1 = AtomicBoolean(false)
+ val checkpoint2 = AtomicBoolean(false)
+ // The remaining two checkpoints should never be hit
+ val checkpoint3 = AtomicBoolean(false)
+ val checkpoint4 = AtomicBoolean(false)
+
+ val result = withTimerOrNull(timeSource) {
+ // The outer timer should trigger during the delay(), and nothing after that should run.
+ startTimer(200.milliseconds)
+ checkpoint1.set(true)
+ withTimerOrNull(timeSource) {
+ startTimer(1.seconds)
+ checkpoint2.set(true)
+ delay(201.milliseconds)
+ checkpoint3.set(true)
+ }
+ checkpoint4.set(true)
+ }
+
+ assertThat(result).isNull()
+ assertThat(checkpoint1.get()).isTrue()
+ assertThat(checkpoint2.get()).isTrue()
+ assertThat(checkpoint3.get()).isFalse()
+ assertThat(checkpoint4.get()).isFalse()
+ }
+}
diff --git a/graphics/graphics-core/api/current.txt b/graphics/graphics-core/api/current.txt
index e10c65e..69d2dd9 100644
--- a/graphics/graphics-core/api/current.txt
+++ b/graphics/graphics-core/api/current.txt
@@ -17,12 +17,12 @@
method public boolean isValid();
method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
method public void release(boolean cancelPending);
- method public void renderFrontBufferedLayer(T? param);
+ method public void renderFrontBufferedLayer(T param);
method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
- method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T? param);
+ method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
@@ -46,12 +46,12 @@
method public boolean isValid();
method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
method public void release(boolean cancelPending);
- method public void renderFrontBufferedLayer(T? param);
+ method public void renderFrontBufferedLayer(T param);
method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
- method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T? param);
+ method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
diff --git a/graphics/graphics-core/api/public_plus_experimental_current.txt b/graphics/graphics-core/api/public_plus_experimental_current.txt
index e10c65e..69d2dd9 100644
--- a/graphics/graphics-core/api/public_plus_experimental_current.txt
+++ b/graphics/graphics-core/api/public_plus_experimental_current.txt
@@ -17,12 +17,12 @@
method public boolean isValid();
method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
method public void release(boolean cancelPending);
- method public void renderFrontBufferedLayer(T? param);
+ method public void renderFrontBufferedLayer(T param);
method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
- method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T? param);
+ method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
@@ -46,12 +46,12 @@
method public boolean isValid();
method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
method public void release(boolean cancelPending);
- method public void renderFrontBufferedLayer(T? param);
+ method public void renderFrontBufferedLayer(T param);
method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
- method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T? param);
+ method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
diff --git a/graphics/graphics-core/api/restricted_current.txt b/graphics/graphics-core/api/restricted_current.txt
index bf4aa7c..0b087b8 100644
--- a/graphics/graphics-core/api/restricted_current.txt
+++ b/graphics/graphics-core/api/restricted_current.txt
@@ -17,12 +17,12 @@
method public boolean isValid();
method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
method public void release(boolean cancelPending);
- method public void renderFrontBufferedLayer(T? param);
+ method public void renderFrontBufferedLayer(T param);
method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface CanvasFrontBufferedRenderer.Callback<T> {
- method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T? param);
+ method @WorkerThread public void onDrawFrontBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, T param);
method @WorkerThread public void onDrawMultiBufferedLayer(android.graphics.Canvas canvas, int bufferWidth, int bufferHeight, java.util.Collection<? extends T> params);
method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
@@ -46,12 +46,12 @@
method public boolean isValid();
method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseComplete);
method public void release(boolean cancelPending);
- method public void renderFrontBufferedLayer(T? param);
+ method public void renderFrontBufferedLayer(T param);
method public void renderMultiBufferedLayer(java.util.Collection<? extends T> params);
}
@kotlin.jvm.JvmDefaultWithCompatibility public static interface GLFrontBufferedRenderer.Callback<T> {
- method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T? param);
+ method @WorkerThread public void onDrawFrontBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, T param);
method @WorkerThread public void onDrawMultiBufferedLayer(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform, java.util.Collection<? extends T> params);
method @WorkerThread public default void onFrontBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
method @WorkerThread public default void onMultiBufferedLayerRenderComplete(androidx.graphics.surface.SurfaceControlCompat frontBufferedLayerSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction);
diff --git a/health/connect/connect-client/api/api_lint.ignore b/health/connect/connect-client/api/api_lint.ignore
index e2d1805..218a3d6 100644
--- a/health/connect/connect-client/api/api_lint.ignore
+++ b/health/connect/connect-client/api/api_lint.ignore
@@ -1,3 +1,7 @@
// Baseline format: 1.0
+GetterSetterNames: field ChangesResponse.changesTokenExpired:
+ Invalid name for boolean property `changesTokenExpired`. Should start with one of `has`, `can`, `should`, `is`.
+
+
MissingJvmstatic: androidx.health.connect.client.HealthConnectClient#ACTION_HEALTH_CONNECT_SETTINGS:
Companion object constants like ACTION_HEALTH_CONNECT_SETTINGS should be using @JvmField, not @JvmStatic; see https://developer.android.com/kotlin/interop#companion_constants
diff --git a/health/health-services-client/api/api_lint.ignore b/health/health-services-client/api/api_lint.ignore
index 844c583..7bcf2c0 100644
--- a/health/health-services-client/api/api_lint.ignore
+++ b/health/health-services-client/api/api_lint.ignore
@@ -1,12 +1,12 @@
// Baseline format: 1.0
-DocumentExceptions: androidx.health.services.client.ExerciseClient#updateExerciseTypeConfigAsync(androidx.health.services.client.data.ExerciseTypeConfig):
- Method ExerciseClient.updateExerciseTypeConfigAsync appears to be throwing kotlin.NotImplementedError; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
-
-
ExecutorRegistration: androidx.health.services.client.ExerciseClient#clearUpdateCallbackAsync(androidx.health.services.client.ExerciseUpdateCallback):
Registration methods should have overload that accepts delivery Executor: `clearUpdateCallbackAsync`
+GetterSetterNames: field ExerciseTypeCapabilities.supportsAutoPauseAndResume:
+ Invalid name for boolean property `supportsAutoPauseAndResume`. Should start with one of `has`, `can`, `should`, `is`.
+
+
InvalidNullabilityOverride: androidx.health.services.client.PassiveListenerService#onBind(android.content.Intent):
Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
InvalidNullabilityOverride: androidx.health.services.client.PassiveListenerService#onBind(android.content.Intent) parameter #0:
diff --git a/javascriptengine/javascriptengine/build.gradle b/javascriptengine/javascriptengine/build.gradle
index d6f3824..4e8c63b 100644
--- a/javascriptengine/javascriptengine/build.gradle
+++ b/javascriptengine/javascriptengine/build.gradle
@@ -26,7 +26,8 @@
api("androidx.annotation:annotation:1.3.0")
api("androidx.concurrent:concurrent-futures:1.0.0")
api("androidx.core:core:1.1.0")
- implementation(libs.guavaAndroid)
+ api(libs.guavaAndroid)
+
androidTestImplementation 'junit:junit:4.12'
annotationProcessor(libs.nullaway)
androidTestImplementation(libs.testExtJunit)
diff --git a/libraryversions.toml b/libraryversions.toml
index 65322bc..77cd29b 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -149,9 +149,9 @@
WEAR_TILES = "1.2.0-alpha04"
WEAR_WATCHFACE = "1.2.0-alpha08"
WEBKIT = "1.8.0-alpha01"
-WINDOW = "1.1.0-beta03"
-WINDOW_EXTENSIONS = "1.1.0-beta02"
-WINDOW_EXTENSIONS_CORE = "1.0.0-beta03"
+WINDOW = "1.1.0-rc01"
+WINDOW_EXTENSIONS = "1.1.0-rc01"
+WINDOW_EXTENSIONS_CORE = "1.0.0-rc01"
WINDOW_SIDECAR = "1.0.0-rc01"
WORK = "2.9.0-alpha01"
diff --git a/lifecycle/lifecycle-livedata-core/api/current.ignore b/lifecycle/lifecycle-livedata-core/api/current.ignore
new file mode 100644
index 0000000..723ad63
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.Observer#onChanged(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.Observer.onChanged(T value)
diff --git a/lifecycle/lifecycle-livedata-core/api/current.txt b/lifecycle/lifecycle-livedata-core/api/current.txt
index f528b4e..eed1a51 100644
--- a/lifecycle/lifecycle-livedata-core/api/current.txt
+++ b/lifecycle/lifecycle-livedata-core/api/current.txt
@@ -26,7 +26,7 @@
}
public fun interface Observer<T> {
- method public void onChanged(T? value);
+ method public void onChanged(T value);
}
}
diff --git a/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt
index f528b4e..eed1a51 100644
--- a/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_current.txt
@@ -26,7 +26,7 @@
}
public fun interface Observer<T> {
- method public void onChanged(T? value);
+ method public void onChanged(T value);
}
}
diff --git a/lifecycle/lifecycle-livedata-core/api/restricted_current.ignore b/lifecycle/lifecycle-livedata-core/api/restricted_current.ignore
new file mode 100644
index 0000000..723ad63
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.Observer#onChanged(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.Observer.onChanged(T value)
diff --git a/lifecycle/lifecycle-livedata-core/api/restricted_current.txt b/lifecycle/lifecycle-livedata-core/api/restricted_current.txt
index f528b4e..eed1a51 100644
--- a/lifecycle/lifecycle-livedata-core/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata-core/api/restricted_current.txt
@@ -26,7 +26,7 @@
}
public fun interface Observer<T> {
- method public void onChanged(T? value);
+ method public void onChanged(T value);
}
}
diff --git a/lifecycle/lifecycle-livedata-ktx/api/current.ignore b/lifecycle/lifecycle-livedata-ktx/api/current.ignore
new file mode 100644
index 0000000..d7e55f2
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.LiveDataScope#emit(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.LiveDataScope.emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
diff --git a/lifecycle/lifecycle-livedata-ktx/api/current.txt b/lifecycle/lifecycle-livedata-ktx/api/current.txt
index bae0928..57284ff 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/current.txt
@@ -15,7 +15,7 @@
}
public interface LiveDataScope<T> {
- method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
method public T? getLatestValue();
property public abstract T? latestValue;
diff --git a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
index bae0928..57284ff 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_current.txt
@@ -15,7 +15,7 @@
}
public interface LiveDataScope<T> {
- method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
method public T? getLatestValue();
property public abstract T? latestValue;
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.ignore b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.ignore
new file mode 100644
index 0000000..d7e55f2
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.LiveDataScope#emit(T, kotlin.coroutines.Continuation<? super kotlin.Unit>) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.lifecycle.LiveDataScope.emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit> arg2)
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
index bae0928..57284ff 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_current.txt
@@ -15,7 +15,7 @@
}
public interface LiveDataScope<T> {
- method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public suspend Object? emit(T value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
method public T? getLatestValue();
property public abstract T? latestValue;
diff --git a/lifecycle/lifecycle-livedata/api/restricted_current.txt b/lifecycle/lifecycle-livedata/api/restricted_current.txt
index bb61b39..6ffd1d9 100644
--- a/lifecycle/lifecycle-livedata/api/restricted_current.txt
+++ b/lifecycle/lifecycle-livedata/api/restricted_current.txt
@@ -4,7 +4,7 @@
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ComputableLiveData<T> {
ctor public ComputableLiveData(optional java.util.concurrent.Executor executor);
ctor public ComputableLiveData();
- method @WorkerThread protected abstract T! compute();
+ method @WorkerThread protected abstract T compute();
method public androidx.lifecycle.LiveData<T> getLiveData();
method public void invalidate();
property public androidx.lifecycle.LiveData<T> liveData;
diff --git a/lifecycle/lifecycle-runtime-compose/api/current.ignore b/lifecycle/lifecycle-runtime-compose/api/current.ignore
new file mode 100644
index 0000000..bfd5f84
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.Lifecycle lifecycle, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.LifecycleOwner lifecycleOwner, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
diff --git a/lifecycle/lifecycle-runtime-compose/api/current.txt b/lifecycle/lifecycle-runtime-compose/api/current.txt
index 95c6977..0686666 100644
--- a/lifecycle/lifecycle-runtime-compose/api/current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/current.txt
@@ -4,8 +4,8 @@
public final class FlowExtKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
}
public final class LifecycleExtKt {
diff --git a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
index 95c6977..0686666 100644
--- a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
@@ -4,8 +4,8 @@
public final class FlowExtKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
}
public final class LifecycleExtKt {
diff --git a/lifecycle/lifecycle-runtime-compose/api/restricted_current.ignore b/lifecycle/lifecycle-runtime-compose/api/restricted_current.ignore
new file mode 100644
index 0000000..bfd5f84
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.Lifecycle lifecycle, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
+InvalidNullConversion: androidx.lifecycle.compose.FlowExtKt#collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State, kotlin.coroutines.CoroutineContext) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.compose.FlowExtKt.collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T> arg1, T initialValue, androidx.lifecycle.LifecycleOwner lifecycleOwner, androidx.lifecycle.Lifecycle.State minActiveState, kotlin.coroutines.CoroutineContext context)
diff --git a/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt b/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
index 95c6977..0686666 100644
--- a/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
@@ -4,8 +4,8 @@
public final class FlowExtKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
- method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+ method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
}
public final class LifecycleExtKt {
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/current.ignore b/lifecycle/lifecycle-viewmodel-savedstate/api/current.ignore
new file mode 100644
index 0000000..41a6e11
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getLiveData(String, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getLiveData(String key, T initialValue)
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getStateFlow(String, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getStateFlow(String key, T initialValue)
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt
index c030c8a..18f47c7 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/current.txt
@@ -14,8 +14,8 @@
method @MainThread public operator boolean contains(String key);
method @MainThread public operator <T> T? get(String key);
method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key);
- method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T? initialValue);
- method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T? initialValue);
+ method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T initialValue);
+ method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T initialValue);
method @MainThread public java.util.Set<java.lang.String> keys();
method @MainThread public <T> T? remove(String key);
method @MainThread public operator <T> void set(String key, T? value);
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt
index c030c8a..18f47c7 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_current.txt
@@ -14,8 +14,8 @@
method @MainThread public operator boolean contains(String key);
method @MainThread public operator <T> T? get(String key);
method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key);
- method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T? initialValue);
- method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T? initialValue);
+ method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T initialValue);
+ method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T initialValue);
method @MainThread public java.util.Set<java.lang.String> keys();
method @MainThread public <T> T? remove(String key);
method @MainThread public operator <T> void set(String key, T? value);
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.ignore b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.ignore
new file mode 100644
index 0000000..41a6e11
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getLiveData(String, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getLiveData(String key, T initialValue)
+InvalidNullConversion: androidx.lifecycle.SavedStateHandle#getStateFlow(String, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter initialValue in androidx.lifecycle.SavedStateHandle.getStateFlow(String key, T initialValue)
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt
index c030c8a..18f47c7 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_current.txt
@@ -14,8 +14,8 @@
method @MainThread public operator boolean contains(String key);
method @MainThread public operator <T> T? get(String key);
method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key);
- method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T? initialValue);
- method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T? initialValue);
+ method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T initialValue);
+ method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T initialValue);
method @MainThread public java.util.Set<java.lang.String> keys();
method @MainThread public <T> T? remove(String key);
method @MainThread public operator <T> void set(String key, T? value);
diff --git a/lifecycle/lifecycle-viewmodel/api/current.ignore b/lifecycle/lifecycle-viewmodel/api/current.ignore
new file mode 100644
index 0000000..68d0b3a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.viewmodel.MutableCreationExtras#set(androidx.lifecycle.viewmodel.CreationExtras.Key<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.lifecycle.viewmodel.MutableCreationExtras.set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t)
diff --git a/lifecycle/lifecycle-viewmodel/api/current.txt b/lifecycle/lifecycle-viewmodel/api/current.txt
index f8457f6..f6e96bc 100644
--- a/lifecycle/lifecycle-viewmodel/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/current.txt
@@ -122,7 +122,7 @@
public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
- method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T? t);
+ method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
}
@kotlin.DslMarker public @interface ViewModelFactoryDsl {
diff --git a/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt
index f8457f6..f6e96bc 100644
--- a/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_current.txt
@@ -122,7 +122,7 @@
public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
- method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T? t);
+ method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
}
@kotlin.DslMarker public @interface ViewModelFactoryDsl {
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.ignore b/lifecycle/lifecycle-viewmodel/api/restricted_current.ignore
new file mode 100644
index 0000000..68d0b3a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.lifecycle.viewmodel.MutableCreationExtras#set(androidx.lifecycle.viewmodel.CreationExtras.Key<T>, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter t in androidx.lifecycle.viewmodel.MutableCreationExtras.set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t)
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
index f8457f6..f6e96bc 100644
--- a/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_current.txt
@@ -122,7 +122,7 @@
public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
- method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T? t);
+ method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T t);
}
@kotlin.DslMarker public @interface ViewModelFactoryDsl {
diff --git a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
index b9cbe32..9bf1025 100644
--- a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
@@ -70,7 +70,8 @@
NullabilityAnnotationsDetector.ISSUE,
IgnoreClassLevelDetector.ISSUE,
ExperimentalPropertyAnnotationDetector.ISSUE,
- UnstableAidlAnnotationDetector.ISSUE,
+ // Temporarily disable AIDL lint check due to b/278871118.
+ // UnstableAidlAnnotationDetector.ISSUE,
// MissingJvmDefaultWithCompatibilityDetector is intentionally left out of the
// registry, see comments on the class for more details.
)
diff --git a/navigation/navigation-common/api/2.6.0-beta01.txt b/navigation/navigation-common/api/2.6.0-beta01.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/2.6.0-beta01.txt
+++ b/navigation/navigation-common/api/2.6.0-beta01.txt
@@ -398,10 +398,10 @@
method public abstract operator T? get(android.os.Bundle bundle, String key);
method public String getName();
method public boolean isNullableAllowed();
- method public abstract T! parseValue(String value);
- method public T! parseValue(String value, T? previousValue);
- method public abstract void put(android.os.Bundle bundle, String key, T? value);
- method public String serializeAsValue(T? value);
+ method public abstract T parseValue(String value);
+ method public T parseValue(String value, T previousValue);
+ method public abstract void put(android.os.Bundle bundle, String key, T value);
+ method public String serializeAsValue(T value);
property public boolean isNullableAllowed;
property public String name;
field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
@@ -438,8 +438,8 @@
public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
ctor public NavType.ParcelableType(Class<D> type);
method public D? get(android.os.Bundle bundle, String key);
- method public D! parseValue(String value);
- method public void put(android.os.Bundle bundle, String key, D? value);
+ method public D parseValue(String value);
+ method public void put(android.os.Bundle bundle, String key, D value);
property public String name;
}
diff --git a/navigation/navigation-common/api/api_lint.ignore b/navigation/navigation-common/api/api_lint.ignore
index 6ada04b..ef9b41b 100644
--- a/navigation/navigation-common/api/api_lint.ignore
+++ b/navigation/navigation-common/api/api_lint.ignore
@@ -89,12 +89,12 @@
Getter should be on the built object, not the builder: method androidx.navigation.PopUpToBuilder.getInclusive()
-GetterSetterNames: androidx.navigation.NavArgumentBuilder#getNullable():
- Symmetric method for `setNullable` must be named `isNullable`; was `getNullable`
-GetterSetterNames: androidx.navigation.NavOptionsBuilder#getLaunchSingleTop():
- Symmetric method for `setLaunchSingleTop` must be named `isLaunchSingleTop`; was `getLaunchSingleTop`
-GetterSetterNames: androidx.navigation.PopUpToBuilder#getInclusive():
- Symmetric method for `setInclusive` must be named `isInclusive`; was `getInclusive`
+GetterSetterNames: field NavArgumentBuilder.nullable:
+ Invalid name for boolean property `nullable`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field NavOptionsBuilder.launchSingleTop:
+ Invalid name for boolean property `launchSingleTop`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PopUpToBuilder.inclusive:
+ Invalid name for boolean property `inclusive`. Should start with one of `has`, `can`, `should`, `is`.
MissingBuildMethod: androidx.navigation.AnimBuilder:
diff --git a/navigation/navigation-common/api/current.ignore b/navigation/navigation-common/api/current.ignore
index a8fe9ea..8eebd5d 100644
--- a/navigation/navigation-common/api/current.ignore
+++ b/navigation/navigation-common/api/current.ignore
@@ -1,3 +1,9 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.navigation.NavType#put(android.os.Bundle, String, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.put(android.os.Bundle bundle, String key, T value)
+InvalidNullConversion: androidx.navigation.NavType.ParcelableType#put(android.os.Bundle, String, D) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.ParcelableType.put(android.os.Bundle bundle, String key, D value)
+
+
RemovedClass: androidx.navigation.NavArgsLazyKt:
Removed class androidx.navigation.NavArgsLazyKt
diff --git a/navigation/navigation-common/api/current.txt b/navigation/navigation-common/api/current.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/current.txt
+++ b/navigation/navigation-common/api/current.txt
@@ -398,10 +398,10 @@
method public abstract operator T? get(android.os.Bundle bundle, String key);
method public String getName();
method public boolean isNullableAllowed();
- method public abstract T! parseValue(String value);
- method public T! parseValue(String value, T? previousValue);
- method public abstract void put(android.os.Bundle bundle, String key, T? value);
- method public String serializeAsValue(T? value);
+ method public abstract T parseValue(String value);
+ method public T parseValue(String value, T previousValue);
+ method public abstract void put(android.os.Bundle bundle, String key, T value);
+ method public String serializeAsValue(T value);
property public boolean isNullableAllowed;
property public String name;
field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
@@ -438,8 +438,8 @@
public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
ctor public NavType.ParcelableType(Class<D> type);
method public D? get(android.os.Bundle bundle, String key);
- method public D! parseValue(String value);
- method public void put(android.os.Bundle bundle, String key, D? value);
+ method public D parseValue(String value);
+ method public void put(android.os.Bundle bundle, String key, D value);
property public String name;
}
diff --git a/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt b/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt
+++ b/navigation/navigation-common/api/public_plus_experimental_2.6.0-beta01.txt
@@ -398,10 +398,10 @@
method public abstract operator T? get(android.os.Bundle bundle, String key);
method public String getName();
method public boolean isNullableAllowed();
- method public abstract T! parseValue(String value);
- method public T! parseValue(String value, T? previousValue);
- method public abstract void put(android.os.Bundle bundle, String key, T? value);
- method public String serializeAsValue(T? value);
+ method public abstract T parseValue(String value);
+ method public T parseValue(String value, T previousValue);
+ method public abstract void put(android.os.Bundle bundle, String key, T value);
+ method public String serializeAsValue(T value);
property public boolean isNullableAllowed;
property public String name;
field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
@@ -438,8 +438,8 @@
public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
ctor public NavType.ParcelableType(Class<D> type);
method public D? get(android.os.Bundle bundle, String key);
- method public D! parseValue(String value);
- method public void put(android.os.Bundle bundle, String key, D? value);
+ method public D parseValue(String value);
+ method public void put(android.os.Bundle bundle, String key, D value);
property public String name;
}
diff --git a/navigation/navigation-common/api/public_plus_experimental_current.txt b/navigation/navigation-common/api/public_plus_experimental_current.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-common/api/public_plus_experimental_current.txt
@@ -398,10 +398,10 @@
method public abstract operator T? get(android.os.Bundle bundle, String key);
method public String getName();
method public boolean isNullableAllowed();
- method public abstract T! parseValue(String value);
- method public T! parseValue(String value, T? previousValue);
- method public abstract void put(android.os.Bundle bundle, String key, T? value);
- method public String serializeAsValue(T? value);
+ method public abstract T parseValue(String value);
+ method public T parseValue(String value, T previousValue);
+ method public abstract void put(android.os.Bundle bundle, String key, T value);
+ method public String serializeAsValue(T value);
property public boolean isNullableAllowed;
property public String name;
field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
@@ -438,8 +438,8 @@
public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
ctor public NavType.ParcelableType(Class<D> type);
method public D? get(android.os.Bundle bundle, String key);
- method public D! parseValue(String value);
- method public void put(android.os.Bundle bundle, String key, D? value);
+ method public D parseValue(String value);
+ method public void put(android.os.Bundle bundle, String key, D value);
property public String name;
}
diff --git a/navigation/navigation-common/api/restricted_2.6.0-beta01.txt b/navigation/navigation-common/api/restricted_2.6.0-beta01.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/restricted_2.6.0-beta01.txt
+++ b/navigation/navigation-common/api/restricted_2.6.0-beta01.txt
@@ -398,10 +398,10 @@
method public abstract operator T? get(android.os.Bundle bundle, String key);
method public String getName();
method public boolean isNullableAllowed();
- method public abstract T! parseValue(String value);
- method public T! parseValue(String value, T? previousValue);
- method public abstract void put(android.os.Bundle bundle, String key, T? value);
- method public String serializeAsValue(T? value);
+ method public abstract T parseValue(String value);
+ method public T parseValue(String value, T previousValue);
+ method public abstract void put(android.os.Bundle bundle, String key, T value);
+ method public String serializeAsValue(T value);
property public boolean isNullableAllowed;
property public String name;
field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
@@ -438,8 +438,8 @@
public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
ctor public NavType.ParcelableType(Class<D> type);
method public D? get(android.os.Bundle bundle, String key);
- method public D! parseValue(String value);
- method public void put(android.os.Bundle bundle, String key, D? value);
+ method public D parseValue(String value);
+ method public void put(android.os.Bundle bundle, String key, D value);
property public String name;
}
diff --git a/navigation/navigation-common/api/restricted_current.ignore b/navigation/navigation-common/api/restricted_current.ignore
index a8fe9ea..8eebd5d 100644
--- a/navigation/navigation-common/api/restricted_current.ignore
+++ b/navigation/navigation-common/api/restricted_current.ignore
@@ -1,3 +1,9 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.navigation.NavType#put(android.os.Bundle, String, T) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.put(android.os.Bundle bundle, String key, T value)
+InvalidNullConversion: androidx.navigation.NavType.ParcelableType#put(android.os.Bundle, String, D) parameter #2:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.navigation.NavType.ParcelableType.put(android.os.Bundle bundle, String key, D value)
+
+
RemovedClass: androidx.navigation.NavArgsLazyKt:
Removed class androidx.navigation.NavArgsLazyKt
diff --git a/navigation/navigation-common/api/restricted_current.txt b/navigation/navigation-common/api/restricted_current.txt
index de2b551..e6d0229 100644
--- a/navigation/navigation-common/api/restricted_current.txt
+++ b/navigation/navigation-common/api/restricted_current.txt
@@ -398,10 +398,10 @@
method public abstract operator T? get(android.os.Bundle bundle, String key);
method public String getName();
method public boolean isNullableAllowed();
- method public abstract T! parseValue(String value);
- method public T! parseValue(String value, T? previousValue);
- method public abstract void put(android.os.Bundle bundle, String key, T? value);
- method public String serializeAsValue(T? value);
+ method public abstract T parseValue(String value);
+ method public T parseValue(String value, T previousValue);
+ method public abstract void put(android.os.Bundle bundle, String key, T value);
+ method public String serializeAsValue(T value);
property public boolean isNullableAllowed;
property public String name;
field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
@@ -438,8 +438,8 @@
public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
ctor public NavType.ParcelableType(Class<D> type);
method public D? get(android.os.Bundle bundle, String key);
- method public D! parseValue(String value);
- method public void put(android.os.Bundle bundle, String key, D? value);
+ method public D parseValue(String value);
+ method public void put(android.os.Bundle bundle, String key, D value);
property public String name;
}
diff --git a/paging/OWNERS b/paging/OWNERS
index dadce6e..5bb78a1 100644
--- a/paging/OWNERS
+++ b/paging/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 413106
+# Bug component: 461228
clarafok@google.com
ilake@google.com
jbwoods@google.com
diff --git a/paging/paging-common/api/api_lint.ignore b/paging/paging-common/api/api_lint.ignore
index dfe3f6e..3748215 100644
--- a/paging/paging-common/api/api_lint.ignore
+++ b/paging/paging-common/api/api_lint.ignore
@@ -11,6 +11,20 @@
Registration methods should have overload that accepts delivery Executor: `addWeakCallback`
+GetterSetterNames: field LoadState.endOfPaginationReached:
+ Invalid name for boolean property `endOfPaginationReached`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.LoadParams.placeholdersEnabled:
+ Invalid name for boolean property `placeholdersEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.invalid:
+ Invalid name for boolean property `invalid`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.jumpingSupported:
+ Invalid name for boolean property `jumpingSupported`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PagingSource.keyReuseSupported:
+ Invalid name for boolean property `keyReuseSupported`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field RemoteMediator.MediatorResult.Success.endOfPaginationReached:
+ Invalid name for boolean property `endOfPaginationReached`. Should start with one of `has`, `can`, `should`, `is`.
+
+
KotlinDefaultParameterOrder: androidx.paging.Pager#Pager(androidx.paging.PagingConfig, Key, androidx.paging.RemoteMediator<Key,Value>, kotlin.jvm.functions.Function0<? extends androidx.paging.PagingSource<Key,Value>>) parameter #1:
Parameter `initialKey` has a default value and should come after all parameters without default values (except for a trailing lambda parameter)
KotlinDefaultParameterOrder: androidx.paging.PagingDataTransforms#insertFooterItem(androidx.paging.PagingData<T>, androidx.paging.TerminalSeparatorType, T) parameter #1:
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt b/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt
index 4702943..b3625ac1 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPagingSource.kt
@@ -25,7 +25,7 @@
import androidx.paging.LoadType.PREPEND
import androidx.paging.LoadType.REFRESH
import androidx.paging.internal.BUGANIZER_URL
-import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.withContext
@@ -36,7 +36,7 @@
@OptIn(DelicateCoroutinesApi::class)
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class LegacyPagingSource<Key : Any, Value : Any>(
- private val fetchDispatcher: CoroutineDispatcher,
+ private val fetchContext: CoroutineContext,
internal val dataSource: DataSource<Key, Value>
) : PagingSource<Key, Value>() {
private var pageSize: Int = PAGE_SIZE_NOT_SET
@@ -106,7 +106,7 @@
pageSize
)
- return withContext(fetchDispatcher) {
+ return withContext(fetchContext) {
dataSource.load(dataSourceParams).run {
LoadResult.Page(
data,
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
index 35ca80a..ac60b3d 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
@@ -502,7 +502,7 @@
val fetchDispatcher = fetchDispatcher ?: Dispatchers.IO
val pagingSource = pagingSource ?: dataSource?.let { dataSource ->
LegacyPagingSource(
- fetchDispatcher = fetchDispatcher,
+ fetchContext = fetchDispatcher,
dataSource = dataSource
)
}
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
index 8091620..ceb1e7f 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
@@ -17,9 +17,9 @@
package androidx.paging
import androidx.paging.PagingSource.LoadResult.Page
-import androidx.testutils.DirectDispatcher
import androidx.testutils.TestDispatcher
import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.collectLatest
@@ -56,7 +56,7 @@
@Test
fun init_invalidDataSource() {
- val testDispatcher = DirectDispatcher
+ val testContext = EmptyCoroutineContext
val dataSource = object : DataSource<Int, Int>(KeyType.ITEM_KEYED) {
var isInvalidCalls = 0
@@ -74,7 +74,7 @@
}
val pagingSource = LegacyPagingSource(
- fetchDispatcher = testDispatcher,
+ fetchContext = testContext,
dataSource = dataSource,
)
@@ -111,7 +111,7 @@
override fun getKey(item: String) = item.hashCode()
}
val pagingSource = LegacyPagingSource(
- fetchDispatcher = Dispatchers.Unconfined,
+ fetchContext = Dispatchers.Unconfined,
dataSource
)
@@ -157,7 +157,7 @@
}
}
val pagingSource = LegacyPagingSource(
- fetchDispatcher = Dispatchers.Unconfined,
+ fetchContext = Dispatchers.Unconfined,
dataSource = dataSource
)
@@ -180,7 +180,7 @@
@Test
fun positional() {
val pagingSource = LegacyPagingSource(
- fetchDispatcher = Dispatchers.Unconfined,
+ fetchContext = Dispatchers.Unconfined,
dataSource = createTestPositionalDataSource()
)
@@ -233,7 +233,7 @@
@Test
fun invalidateFromPagingSource() {
val pagingSource = LegacyPagingSource(
- fetchDispatcher = Dispatchers.Unconfined,
+ fetchContext = Dispatchers.Unconfined,
dataSource = createTestPositionalDataSource()
)
val dataSource = pagingSource.dataSource
@@ -259,7 +259,7 @@
@Test
fun invalidateFromDataSource() {
val pagingSource = LegacyPagingSource(
- fetchDispatcher = Dispatchers.Unconfined,
+ fetchContext = Dispatchers.Unconfined,
dataSource = createTestPositionalDataSource()
)
val dataSource = pagingSource.dataSource
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
index 47fe02e4..20a1116 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
@@ -19,7 +19,7 @@
import androidx.paging.LoadType.PREPEND
import androidx.paging.LoadType.REFRESH
import androidx.paging.PageEvent.Drop
-import androidx.testutils.DirectDispatcher
+import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
@@ -290,7 +290,7 @@
)
}
- private val differ = TestPagingDataDiffer<String>(DirectDispatcher)
+ private val differ = TestPagingDataDiffer<String>(EmptyCoroutineContext)
private lateinit var pagingData: PagingData<String>
@Before
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
index fdd21d7..9253657 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
@@ -21,7 +21,6 @@
import androidx.paging.LoadType.PREPEND
import androidx.paging.PageEvent.Drop
import androidx.paging.PagingSource.LoadResult
-import androidx.testutils.DirectDispatcher
import androidx.testutils.MainDispatcherRule
import androidx.testutils.TestDispatcher
import com.google.common.truth.Truth.assertThat
@@ -2039,11 +2038,6 @@
}
private fun runTest(
- scope: CoroutineScope = CoroutineScope(DirectDispatcher),
- differ: SimpleDiffer = SimpleDiffer(
- differCallback = dummyDifferCallback,
- coroutineScope = scope,
- ),
loadDispatcher: TestDispatcher = TestDispatcher(),
initialKey: Int? = null,
pagingSources: MutableList<TestPagingSource> = mutableListOf(),
@@ -2065,11 +2059,15 @@
uiReceivers: List<TrackableUiReceiverWrapper>,
hintReceivers: List<TrackableHintReceiverWrapper>
) -> Unit
- ) {
+ ) = testScope.runTest {
+ val differ = SimpleDiffer(
+ differCallback = dummyDifferCallback,
+ coroutineScope = this,
+ )
val uiReceivers = mutableListOf<TrackableUiReceiverWrapper>()
val hintReceivers = mutableListOf<TrackableHintReceiverWrapper>()
- val collection = scope.launch {
+ val collection = launch {
pager.flow
.map { pagingData ->
PagingData(
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index 476ad28..599b0b2 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -25,6 +25,6 @@
kotlin.code.style=official
# Disable docs
androidx.enableDocumentation=false
-androidx.playground.snapshotBuildId=9912543
-androidx.playground.metalavaBuildId=9883460
+androidx.playground.snapshotBuildId=9971607
+androidx.playground.metalavaBuildId=9975079
androidx.studio.type=playground
diff --git a/privacysandbox/OWNERS b/privacysandbox/OWNERS
index 3d0f6bf..fcd4bae 100644
--- a/privacysandbox/OWNERS
+++ b/privacysandbox/OWNERS
@@ -1,4 +1,4 @@
-# Bug component: 1314839
+# Bug component: 1248632
abz@google.com
ltenorio@google.com
nicoroulet@google.com
diff --git a/privacysandbox/ads/OWNERS b/privacysandbox/ads/OWNERS
index 213fd78..dc742a8 100644
--- a/privacysandbox/ads/OWNERS
+++ b/privacysandbox/ads/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 1248632
# adservices.measurement OWNERS
arpanah@google.com # Measurement Primary PoC
lmohanan@google.com
diff --git a/privacysandbox/ads/ads-adservices/api/api_lint.ignore b/privacysandbox/ads/ads-adservices/api/api_lint.ignore
new file mode 100644
index 0000000..135b6f0
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+GetterSetterNames: field WebSourceParams.debugKeyAllowed:
+ Invalid name for boolean property `debugKeyAllowed`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field WebTriggerParams.debugKeyAllowed:
+ Invalid name for boolean property `debugKeyAllowed`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/privacysandbox/sdkruntime/OWNERS b/privacysandbox/sdkruntime/OWNERS
index 1ee0dca..5f61b4f 100644
--- a/privacysandbox/sdkruntime/OWNERS
+++ b/privacysandbox/sdkruntime/OWNERS
@@ -1 +1,2 @@
+# Bug component: 1347351
akulakov@google.com
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
index 41dbd62..0f0d2f7 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyInterfaceStubDelegate.kt
@@ -5,19 +5,19 @@
import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
import kotlin.Int
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class MyInterfaceStubDelegate internal constructor(
public val `delegate`: MyInterface,
public val context: Context,
) : IMyInterface.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doSomething(request: ParcelableRequest,
transactionCallback: IResponseTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doSomething(RequestConverter(context).fromParcelable(request))
transactionCallback.onSuccess(ResponseConverter(context).toParcelable(result))
@@ -32,8 +32,7 @@
public override fun getMyInterface(input: IMyInterface,
transactionCallback: IMyInterfaceTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.getMyInterface((input as MyInterfaceStubDelegate).delegate)
transactionCallback.onSuccess(MyInterfaceStubDelegate(result, context))
@@ -48,8 +47,7 @@
public override fun getMySecondInterface(input: IMySecondInterface,
transactionCallback: IMySecondInterfaceTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.getMySecondInterface((input as
MySecondInterfaceStubDelegate).delegate)
@@ -64,6 +62,8 @@
}
public override fun doMoreStuff(x: Int): Unit {
- delegate.doMoreStuff(x)
+ coroutineScope.launch {
+ delegate.doMoreStuff(x)
+ }
}
}
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
index 4419c33..6dbf1b5f 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySdkStubDelegate.kt
@@ -7,22 +7,22 @@
import kotlin.Int
import kotlin.IntArray
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class MySdkStubDelegate internal constructor(
public val `delegate`: MySdk,
public val context: Context,
) : IMySdk.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doStuff(
x: Int,
y: Int,
transactionCallback: IStringTransactionCallback,
): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doStuff(x, y)
transactionCallback.onSuccess(result)
@@ -37,8 +37,7 @@
public override fun handleRequest(request: ParcelableRequest,
transactionCallback: IResponseTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.handleRequest(RequestConverter(context).fromParcelable(request))
transactionCallback.onSuccess(ResponseConverter(context).toParcelable(result))
@@ -53,8 +52,7 @@
public override fun logRequest(request: ParcelableRequest,
transactionCallback: IUnitTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
delegate.logRequest(RequestConverter(context).fromParcelable(request))
transactionCallback.onSuccess()
@@ -68,17 +66,20 @@
}
public override fun setListener(listener: IMyCallback): Unit {
- delegate.setListener(MyCallbackClientProxy(listener, context))
+ coroutineScope.launch {
+ delegate.setListener(MyCallbackClientProxy(listener, context))
+ }
}
public override fun doMoreStuff(): Unit {
- delegate.doMoreStuff()
+ coroutineScope.launch {
+ delegate.doMoreStuff()
+ }
}
public override fun getMyInterface(input: IMyInterface,
transactionCallback: IMyInterfaceTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.getMyInterface((input as MyInterfaceStubDelegate).delegate)
transactionCallback.onSuccess(MyInterfaceStubDelegate(result, context))
@@ -92,7 +93,9 @@
}
public override fun mutateMySecondInterface(input: IMySecondInterface): Unit {
- delegate.mutateMySecondInterface((input as MySecondInterfaceStubDelegate).delegate)
+ coroutineScope.launch {
+ delegate.mutateMySecondInterface((input as MySecondInterfaceStubDelegate).delegate)
+ }
}
public override fun handleNullablePrimitives(
@@ -100,8 +103,7 @@
y: IntArray,
transactionCallback: IListStringTransactionCallback,
): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.handleNullablePrimitives(x.firstOrNull(), y.firstOrNull())
transactionCallback.onSuccess(if (result == null) arrayOf() else arrayOf(result))
@@ -116,8 +118,7 @@
public override fun handleNullableValues(maybeRequest: ParcelableRequest?,
transactionCallback: IResponseTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.handleNullableValues(maybeRequest?.let { notNullValue ->
RequestConverter(context).fromParcelable(notNullValue) })
@@ -134,8 +135,7 @@
public override fun handleNullableInterfaces(maybeCallback: IMyCallback?,
transactionCallback: IMyInterfaceTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.handleNullableInterfaces(maybeCallback?.let { notNullValue ->
MyCallbackClientProxy(notNullValue, context) })
@@ -152,8 +152,7 @@
public override fun returnUiInterface(transactionCallback: IMyUiInterfaceTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.returnUiInterface()
transactionCallback.onSuccess(IMyUiInterfaceCoreLibInfoAndBinderWrapperConverter.toParcelable(result.toCoreLibInfo(context),
@@ -168,6 +167,8 @@
}
public override fun acceptUiInterfaceParam(input: IMyUiInterface): Unit {
- delegate.acceptUiInterfaceParam((input as MyUiInterfaceStubDelegate).delegate)
+ coroutineScope.launch {
+ delegate.acceptUiInterfaceParam((input as MyUiInterfaceStubDelegate).delegate)
+ }
}
}
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
index 0f6d47f..817f83a 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MySecondInterfaceStubDelegate.kt
@@ -12,19 +12,19 @@
import kotlin.LongArray
import kotlin.String
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class MySecondInterfaceStubDelegate internal constructor(
public val `delegate`: MySecondInterface,
public val context: Context,
) : IMySecondInterface.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doIntStuff(x.toList())
transactionCallback.onSuccess(result.toIntArray())
@@ -39,8 +39,7 @@
public override fun doCharStuff(x: CharArray, transactionCallback: IListCharTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doCharStuff(x.toList())
transactionCallback.onSuccess(result.toCharArray())
@@ -55,8 +54,7 @@
public override fun doFloatStuff(x: FloatArray,
transactionCallback: IListFloatTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doFloatStuff(x.toList())
transactionCallback.onSuccess(result.toFloatArray())
@@ -71,8 +69,7 @@
public override fun doLongStuff(x: LongArray, transactionCallback: IListLongTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doLongStuff(x.toList())
transactionCallback.onSuccess(result.toLongArray())
@@ -87,8 +84,7 @@
public override fun doDoubleStuff(x: DoubleArray,
transactionCallback: IListDoubleTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doDoubleStuff(x.toList())
transactionCallback.onSuccess(result.toDoubleArray())
@@ -103,8 +99,7 @@
public override fun doBooleanStuff(x: BooleanArray,
transactionCallback: IListBooleanTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doBooleanStuff(x.toList())
transactionCallback.onSuccess(result.toBooleanArray())
@@ -119,8 +114,7 @@
public override fun doShortStuff(x: IntArray, transactionCallback: IListShortTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doShortStuff(x.map { it.toShort() }.toList())
transactionCallback.onSuccess(result.map { it.toInt() }.toIntArray())
@@ -135,8 +129,7 @@
public override fun doStringStuff(x: Array<String>,
transactionCallback: IListStringTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doStringStuff(x.toList())
transactionCallback.onSuccess(result.toTypedArray())
@@ -151,8 +144,7 @@
public override fun doValueStuff(x: Array<ParcelableRequest>,
transactionCallback: IListResponseTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doValueStuff(x.map { RequestConverter(context).fromParcelable(it)
}.toList())
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
index d25a92d..b234751 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/MyUiInterfaceStubDelegate.kt
@@ -3,12 +3,19 @@
import android.content.Context
import kotlin.Int
import kotlin.Unit
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
public class MyUiInterfaceStubDelegate internal constructor(
public val `delegate`: MyUiInterface,
public val context: Context,
) : IMyUiInterface.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doSomethingForUi(x: Int, y: Int): Unit {
- delegate.doSomethingForUi(x, y)
+ coroutineScope.launch {
+ delegate.doSomethingForUi(x, y)
+ }
}
}
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
index 4b68dab..594b8e3 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/myotherpackage/MyOtherPackageInterfaceStubDelegate.kt
@@ -6,23 +6,25 @@
import com.mysdk.TransportCancellationCallback
import kotlin.Int
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class MyOtherPackageInterfaceStubDelegate internal constructor(
public val `delegate`: MyOtherPackageInterface,
public val context: Context,
) : IMyOtherPackageInterface.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doStuff(x: Int): Unit {
- delegate.doStuff(x)
+ coroutineScope.launch {
+ delegate.doStuff(x)
+ }
}
public override fun useDataClass(x: ParcelableMyOtherPackageDataClass,
transactionCallback: IUnitTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
delegate.useDataClass(MyOtherPackageDataClassConverter(context).fromParcelable(x))
transactionCallback.onSuccess()
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
index d4fcb8f..661bf8c 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MyMainPackageInterfaceStubDelegate.kt
@@ -7,19 +7,19 @@
import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
import kotlin.IntArray
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class MyMainPackageInterfaceStubDelegate internal constructor(
public val `delegate`: MyMainPackageInterface,
public val context: Context,
) : IMyMainPackageInterface.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doIntStuff(x: IntArray, transactionCallback: IListIntTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doIntStuff(x.toList())
transactionCallback.onSuccess(result.toIntArray())
@@ -34,8 +34,7 @@
public override fun useDataClass(x: ParcelableMyOtherPackageDataClass,
transactionCallback: IMyOtherPackageDataClassTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result =
delegate.useDataClass(MyOtherPackageDataClassConverter(context).fromParcelable(x))
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
index 1a2beff..b9c2fb5 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkwithpackages/output/com/mysdk/MySdkStubDelegate.kt
@@ -6,22 +6,22 @@
import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
import kotlin.Int
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class MySdkStubDelegate internal constructor(
public val `delegate`: MySdk,
public val context: Context,
) : IMySdk.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doStuff(
x: Int,
y: Int,
transactionCallback: IStringTransactionCallback,
): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doStuff(x, y)
transactionCallback.onSuccess(result)
@@ -36,8 +36,7 @@
public override
fun getMyInterface(transactionCallback: IMyMainPackageInterfaceTransactionCallback): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.getMyInterface()
transactionCallback.onSuccess(MyMainPackageInterfaceStubDelegate(result, context))
@@ -53,8 +52,7 @@
public override
fun getMyOtherPackageInterface(transactionCallback: IMyOtherPackageInterfaceTransactionCallback):
Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.getMyOtherPackageInterface()
transactionCallback.onSuccess(MyOtherPackageInterfaceStubDelegate(result, context))
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
index e20ab2c..c46719e 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/withoutruntimelibrarysdk/output/com/mysdk/WithoutRuntimeLibrarySdkStubDelegate.kt
@@ -4,22 +4,22 @@
import com.mysdk.PrivacySandboxThrowableParcelConverter.toThrowableParcel
import kotlin.Int
import kotlin.Unit
-import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
public class WithoutRuntimeLibrarySdkStubDelegate internal constructor(
public val `delegate`: WithoutRuntimeLibrarySdk,
public val context: Context,
) : IWithoutRuntimeLibrarySdk.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun doStuff(
x: Int,
y: Int,
transactionCallback: IStringTransactionCallback,
): Unit {
- @OptIn(DelicateCoroutinesApi::class)
- val job = GlobalScope.launch(Dispatchers.Main) {
+ val job = coroutineScope.launch {
try {
val result = delegate.doStuff(x, y)
transactionCallback.onSuccess(result)
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
index f4043ef..d103c41 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/callbacks/output/com/sdkwithcallbacks/SdkCallbackStubDelegate.kt
@@ -3,23 +3,36 @@
import com.sdkwithcallbacks.ResponseConverter.fromParcelable
import kotlin.Int
import kotlin.Unit
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
public class SdkCallbackStubDelegate internal constructor(
public val `delegate`: SdkCallback,
) : ISdkCallback.Stub() {
+ private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Main)
+
public override fun onCompleteInterface(myInterface: IMyInterface): Unit {
- delegate.onCompleteInterface(MyInterfaceClientProxy(myInterface))
+ coroutineScope.launch {
+ delegate.onCompleteInterface(MyInterfaceClientProxy(myInterface))
+ }
}
public override fun onEmptyEvent(): Unit {
- delegate.onEmptyEvent()
+ coroutineScope.launch {
+ delegate.onEmptyEvent()
+ }
}
public override fun onPrimitivesReceived(x: Int, y: Int): Unit {
- delegate.onPrimitivesReceived(x, y)
+ coroutineScope.launch {
+ delegate.onPrimitivesReceived(x, y)
+ }
}
public override fun onValueReceived(response: ParcelableResponse): Unit {
- delegate.onValueReceived(fromParcelable(response))
+ coroutineScope.launch {
+ delegate.onValueReceived(fromParcelable(response))
+ }
}
}
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt
index a15104c..39efaca 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/KotlinPoetSpecs.kt
@@ -145,21 +145,28 @@
}
object SpecNames {
- val contextPropertyName = "context"
+ const val contextPropertyName = "context"
- val dispatchersMainClass = ClassName("kotlinx.coroutines", "Dispatchers", "Main")
- val delicateCoroutinesApiClass = ClassName("kotlinx.coroutines", "DelicateCoroutinesApi")
- val globalScopeClass = ClassName("kotlinx.coroutines", "GlobalScope")
- val suspendCancellableCoroutineMethod =
- MemberName("kotlinx.coroutines", "suspendCancellableCoroutine", isExtension = true)
+ // Kotlin coroutines
val resumeWithExceptionMethod =
MemberName("kotlin.coroutines", "resumeWithException", isExtension = true)
- val launchMethod = MemberName("kotlinx.coroutines", "launch", isExtension = true)
+ // KotlinX coroutines
+ val coroutineScopeClass = ClassName("kotlinx.coroutines", "CoroutineScope")
+ val dispatchersMainClass = ClassName("kotlinx.coroutines", "Dispatchers", "Main")
+ val launchMethod = MemberName("kotlinx.coroutines", "launch", isExtension = true)
+ val suspendCancellableCoroutineMethod =
+ MemberName("kotlinx.coroutines", "suspendCancellableCoroutine", isExtension = true)
+
+ // Java
val stackTraceElementClass = ClassName("java.lang", "StackTraceElement")
+
+ // Android
val iBinderClass = ClassName("android.os", "IBinder")
val bundleClass = ClassName("android.os", "Bundle")
val contextClass = ClassName("android.content", "Context")
val viewClass = ClassName("android.view", "View")
+
+ // Privacy Sandbox UI
val toCoreLibInfoMethod = MemberName("androidx.privacysandbox.ui.provider", "toCoreLibInfo")
}
\ No newline at end of file
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
index fc18f64..85f2dfa 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/StubDelegatesGenerator.kt
@@ -19,7 +19,9 @@
import androidx.privacysandbox.tools.core.generator.GenerationTarget.SERVER
import androidx.privacysandbox.tools.core.generator.SpecNames.contextClass
import androidx.privacysandbox.tools.core.generator.SpecNames.contextPropertyName
-import androidx.privacysandbox.tools.core.generator.SpecNames.delicateCoroutinesApiClass
+import androidx.privacysandbox.tools.core.generator.SpecNames.coroutineScopeClass
+import androidx.privacysandbox.tools.core.generator.SpecNames.dispatchersMainClass
+import androidx.privacysandbox.tools.core.generator.SpecNames.launchMethod
import androidx.privacysandbox.tools.core.model.AnnotatedInterface
import androidx.privacysandbox.tools.core.model.Method
import androidx.privacysandbox.tools.core.model.Types
@@ -42,6 +44,8 @@
ClassName(packageName, TransportCancellationGenerator.className)
}
+ private val coroutineScopePropertyName = "coroutineScope"
+
/**
* Generates a StubDelegate for this interface.
*
@@ -77,6 +81,12 @@
KModifier.INTERNAL,
)
+ val coroutineProperty =
+ PropertySpec.builder(coroutineScopePropertyName, coroutineScopeClass)
+ .addModifiers(KModifier.PRIVATE)
+ .initializer(CodeBlock.of("%T(%T)", coroutineScopeClass, dispatchersMainClass))
+ .build()
+ addProperty(coroutineProperty)
addFunctions(annotatedInterface.methods.map(::toFunSpec))
}
@@ -95,12 +105,8 @@
addModifiers(KModifier.OVERRIDE)
addParameters(getParameters(method))
addCode {
- addStatement("@OptIn(%T::class)", delicateCoroutinesApiClass)
addControlFlow(
- "val job = %T.%M(%T)",
- SpecNames.globalScopeClass,
- SpecNames.launchMethod,
- SpecNames.dispatchersMainClass
+ "val job = %L.%M", coroutineScopePropertyName, launchMethod
) {
addControlFlow("try") {
addStatement {
@@ -141,7 +147,11 @@
private fun toNonSuspendFunSpec(method: Method) = FunSpec.builder(method.name).build {
addModifiers(KModifier.OVERRIDE)
addParameters(getParameters(method))
- addStatement { add(getDelegateCallBlock(method)) }
+ addCode(CodeBlock.builder().build {
+ addControlFlow("%L.%M", coroutineScopePropertyName, launchMethod) {
+ addStatement { add(getDelegateCallBlock(method)) }
+ }
+ })
}
private fun getParameters(method: Method) = buildList {
diff --git a/profileinstaller/integration-tests/profile-verification/build.gradle b/profileinstaller/integration-tests/profile-verification/build.gradle
index aa13d76..adb81bb 100644
--- a/profileinstaller/integration-tests/profile-verification/build.gradle
+++ b/profileinstaller/integration-tests/profile-verification/build.gradle
@@ -1,3 +1,9 @@
+import com.google.common.io.Files
+import org.apache.commons.compress.utils.IOUtils
+
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
+
/*
* Copyright (C) 2022 The Android Open Source Project
*
@@ -20,23 +26,58 @@
}
// This task copies the apks provided by the `apkAssets` configuration and places them in the
-// assets folder. This allows a build time generation of the sample apps.
-def copyApkTaskProvider = tasks.register("copyApkAssets", Copy) {
- description = "Copies the asset apks provided by profile-verification-sample projects"
- dependsOn(configurations.getByName("apkAssets"))
- from(configurations.getByName("apkAssets").incoming.artifactView {}.files)
- into(layout.buildDirectory.dir("intermediates/apkAssets"))
+// assets folder. It also extracts the profiles to make them available to the test app.
+// This allows a build time generation of the sample apps.
+abstract class PrepareAssetsTask extends DefaultTask {
- // Note that the artifact directory included contain multiple output-metadata.json files built
- // with the apks. Since we're not interested in those we can simply exclude duplicates.
- duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
+ @InputFiles
+ @PathSensitive(PathSensitivity.NONE)
+ abstract ConfigurableFileCollection getApkAssetsFolders()
+
+ @OutputDirectory
+ abstract DirectoryProperty getOutputDir()
+
+ @TaskAction
+ void exec() {
+ for (File folder : apkAssetsFolders.files) {
+ for (File file : folder.listFiles()) {
+
+ // Consider only apk files (skip json metadata)
+ if (!file.name.endsWith(".apk")) {
+ continue
+ }
+
+ // Copies the apk in the output dir
+ Files.copy(file, outputDir.file(file.name).get().asFile)
+
+ // Extract the profile in the apk and places it in the assets
+ ZipFile zipFile = new ZipFile(file)
+ extractZipEntry(zipFile, "assets/dexopt/baseline.prof", "${file.name}_baseline.prof")
+ extractZipEntry(zipFile, "assets/dexopt/baseline.profm", "${file.name}_baseline.profm")
+ }
+ }
+ }
+
+ private void extractZipEntry(ZipFile zipFile, String zipEntryName, String outputFileName) {
+ ZipEntry entry = zipFile.entries().find { it.name == zipEntryName }
+ File outputFile = outputDir.file(outputFileName).get().asFile
+ try (FileOutputStream os = new FileOutputStream(outputFile)) {
+ IOUtils.copy(zipFile.getInputStream(entry), os)
+ }
+ }
+}
+
+def prepareAssetsTaskProvider = tasks.register("prepareAssets", PrepareAssetsTask) {
+ description = "Copies the apks and profiles provided by profile-verification-sample projects into the assets."
+ apkAssetsFolders.from(configurations.getByName("apkAssets").incoming.artifactView {}.files)
+ outputDir.set(layout.buildDirectory.dir("intermediates/profile-verification-assets"))
}
android {
defaultConfig {
minSdkVersion 23
}
- sourceSets.androidTest.assets.srcDir(copyApkTaskProvider)
+ sourceSets.androidTest.assets.srcDir(prepareAssetsTaskProvider.map { it.outputDir })
namespace "androidx.profileinstaller.integration.profileverification"
}
@@ -71,5 +112,5 @@
// It makes sure that the apks are generated before the assets are packed.
afterEvaluate {
- tasks.named("generateDebugAndroidTestAssets").configure { it.dependsOn(copyApkTaskProvider) }
+ tasks.named("generateDebugAndroidTestAssets").configure { it.dependsOn(prepareAssetsTaskProvider) }
}
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.prof b/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.prof
deleted file mode 100644
index dafbbbb..0000000
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.prof
+++ /dev/null
Binary files differ
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.profm b/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.profm
deleted file mode 100644
index d72fd91..0000000
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/assets/baseline.profm
+++ /dev/null
Binary files differ
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt
index 0516ad7..fcef429 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnGeneratedProfiles.kt
@@ -54,9 +54,6 @@
@Before
fun setUp() {
- // TODO: to re-enable for api 34 (b/276970167)
- Assume.assumeTrue(!isApi34)
-
// Note that this test fails on emulator api 30 (b/251540646)
Assume.assumeTrue(!isApi30)
withPackageName(packageName) { uninstall() }
@@ -68,8 +65,7 @@
}
@Test
- fun generatedBaselineProfile() =
- withPackageName(packageName) {
+ fun profileInstallerInstallation() = withPackageName(packageName) {
// Installs the apk
install(apkName = apk, withProfile = false)
@@ -94,4 +90,17 @@
hasCurrentProfile(false)
}
}
+
+ @Test
+ fun packageManagerInstallation() = withPackageName(packageName) {
+
+ // Install with reference profile.
+ install(apkName = apk, withProfile = true)
+ start(ACTIVITY_NAME)
+ evaluateUI {
+ hasReferenceProfile(true)
+ hasCurrentProfile(true)
+ profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+ }
+ }
}
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt
index 34cc956..6e3fae7 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationOnUnsupportedApiVersions.kt
@@ -29,9 +29,6 @@
@Before
fun setUp() {
- // TODO: to re-enable for api 34 (b/276970167)
- Assume.assumeTrue(!isApi34)
-
// This test runs only on selected api version currently unsupported by profile verifier
Assume.assumeTrue(
Build.VERSION.SDK_INT < Build.VERSION_CODES.P ||
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt
index fe47284..6cbc48f 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithProfileInstallerInitializer.kt
@@ -17,6 +17,7 @@
package androidx.profileinstaller.integration.profileverification
import androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE
+import androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING
import androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION
import androidx.profileinstaller.ProfileVersion
import androidx.test.filters.LargeTest
@@ -47,9 +48,6 @@
@Before
fun setUp() = withPackageName(PACKAGE_NAME_WITH_INITIALIZER) {
- // TODO: to re-enable for api 34 (b/276970167)
- assumeTrue(!isApi34)
-
// Note that this test fails on emulator api 30 (b/251540646)
assumeTrue(!isApi30)
uninstall()
@@ -171,7 +169,14 @@
install(apkName = APK_WITH_INITIALIZER_V3, withProfile = true)
start(ACTIVITY_NAME)
evaluateUI {
- profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+
+ // Taimen Api 28 and Cuttlefish Api 29 behave differently.
+ if ((isApi29 && isCuttlefish) || (isApi28 && !isCuttlefish)) {
+ profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING)
+ } else {
+ profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+ }
+
hasReferenceProfile(true)
hasCurrentProfile(true)
}
@@ -226,7 +231,13 @@
install(apkName = APK_WITH_INITIALIZER_V3, withProfile = true)
start(ACTIVITY_NAME)
evaluateUI {
- profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+
+ // Taimen Api 28 and Cuttlefish Api 29 behave differently.
+ if ((isApi29 && isCuttlefish) || (isApi28 && !isCuttlefish)) {
+ profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING)
+ } else {
+ profileInstalled(RESULT_CODE_COMPILED_WITH_PROFILE)
+ }
hasReferenceProfile(true)
hasCurrentProfile(true)
}
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt
index 63401b6..cca5f12 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/ProfileVerificationTestWithoutProfileInstallerInitializer.kt
@@ -50,9 +50,6 @@
@Before
fun setUp() = withPackageName(PACKAGE_NAME_WITHOUT_INITIALIZER) {
- // TODO: to re-enable for api 34 (b/276970167)
- assumeTrue(!isApi34)
-
// Note that this test fails on emulator api 30 (b/251540646)
assumeTrue(!isApi30)
uninstall()
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt
index 91647ac..3e27464 100644
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt
+++ b/profileinstaller/integration-tests/profile-verification/src/androidTest/java/androidx/profileinstaller/integration/profileverification/TestManager.kt
@@ -21,7 +21,6 @@
import android.os.ParcelFileDescriptor
import android.util.Log
import androidx.concurrent.futures.DirectExecutor
-import androidx.core.os.BuildCompat
import androidx.profileinstaller.DeviceProfileWriter
import androidx.profileinstaller.ProfileInstaller
import androidx.test.platform.app.InstrumentationRegistry
@@ -74,24 +73,6 @@
try {
- // First writes in a temp file the apk from the assets
- val tmpApkFile = File(dirUsableByAppAndShell, "tmp_$apkName").also { file ->
- file.delete()
- file.createNewFile()
- file.deleteOnExit()
- file.outputStream().use { instrumentation.context.assets.open(apkName).copyTo(it) }
- }
- cleanUpBlocks.add { tmpApkFile.delete() }
-
- // Then moves it to a destination that can be used to install it
- val destApkPath = "$TEMP_DIR/$apkName"
- assertThat(executeCommand("mv ${tmpApkFile.absolutePath} $destApkPath")).isEmpty()
- cleanUpBlocks.add { executeCommand("rm $destApkPath") }
-
- // This mimes the behaviour of `adb install-multiple` using an install session.
- // For reference:
- // https://source.corp.google.com/android-internal/packages/modules/adb/client/adb_install.cpp
-
// Creates an install session
val installCreateOutput = executeCommand("pm install-create -t").first().trim()
val sessionId = REGEX_SESSION_ID
@@ -102,9 +83,32 @@
.value
.toLong()
+ // Creates tmp dir for this session
+ val baseTmpFolder = "$TEMP_DIR/$sessionId"
+ assertThat(executeCommand("mkdir -p $baseTmpFolder")).isEmpty()
+ cleanUpBlocks.add { executeCommand("rm -Rf $baseTmpFolder") }
+
+ // First writes in a temp file the apk from the assets
+ val tmpApkFile = File(dirUsableByAppAndShell, "tmp_$apkName").also { file ->
+ file.delete()
+ file.createNewFile()
+ file.deleteOnExit()
+ file.outputStream().use { instrumentation.context.assets.open(apkName).copyTo(it) }
+ }
+ cleanUpBlocks.add { tmpApkFile.delete() }
+
+ // Then moves it to a destination that can be used to install it
+ val destApkPath = "$baseTmpFolder/base.apk"
+ assertThat(executeCommand("mv ${tmpApkFile.absolutePath} $destApkPath")).isEmpty()
+ cleanUpBlocks.add { executeCommand("rm $destApkPath") }
+
+ // This mimes the behaviour of `adb install-multiple` using an install session.
+ // For reference:
+ // https://source.corp.google.com/android-internal/packages/modules/adb/client/adb_install.cpp
+
// Adds the base apk to the install session
val successBaseApk =
- executeCommand("pm install-write $sessionId base.apk $TEMP_DIR/$apkName")
+ executeCommand("pm install-write $sessionId base.apk $destApkPath")
.first()
.trim()
.startsWith("Success")
@@ -129,8 +133,8 @@
DirectExecutor.INSTANCE,
EMPTY_DIAGNOSTICS,
apkName,
- BASELINE_PROF,
- BASELINE_PROFM,
+ "${apkName}_$BASELINE_PROF",
+ "${apkName}_$BASELINE_PROFM",
tmpProfileProfFile
)
if (!deviceProfileWriter.deviceAllowsProfileInstallerAotWrites()) {
@@ -165,7 +169,7 @@
cleanUpBlocks.add { tmpDmFile.delete() }
// Then moves it to a destination that can be used to install it
- val dmFilePath = "$TEMP_DIR/$DM_FILE_NAME"
+ val dmFilePath = "$baseTmpFolder/$DM_FILE_NAME"
executeCommand("mv ${tmpDmFile.absolutePath} $dmFilePath")
cleanUpBlocks.add { executeCommand("rm $dmFilePath") }
@@ -196,7 +200,7 @@
// Runs all the clean up blocks. This will clean up also partial operations in case
// there is an issue during install
- cleanUpBlocks.forEach { it() }
+ cleanUpBlocks.reversed().forEach { it() }
}
}
@@ -260,7 +264,7 @@
companion object {
private const val TAG = "TestManager"
- private const val TEMP_DIR = "/data/local/tmp/"
+ private const val TEMP_DIR = "/data/local/tmp"
private const val UI_TIMEOUT = 20000L
private const val BASELINE_PROF = "baseline.prof"
private const val BASELINE_PROFM = "baseline.profm"
@@ -284,6 +288,10 @@
.that(lines[2].toBoolean())
.isEqualTo(value)
}
+
+ val isCuttlefish by lazy {
+ executeCommand("getprop ro.product.product.model").any { "cuttlefish" in it.lowercase() }
+ }
}
private val EMPTY_DIAGNOSTICS: ProfileInstaller.DiagnosticsCallback =
@@ -301,7 +309,8 @@
private fun <T> T?.throwIfNull(message: String): T = this ?: throw Exception(message)
val isApi30 by lazy { Build.VERSION.SDK_INT == Build.VERSION_CODES.R }
-val isApi34 by lazy { BuildCompat.isAtLeastU() }
+val isApi28 by lazy { Build.VERSION.SDK_INT == Build.VERSION_CODES.P }
+val isApi29 by lazy { Build.VERSION.SDK_INT == Build.VERSION_CODES.Q }
const val PACKAGE_NAME_WITH_INITIALIZER =
"androidx.profileinstaller.integration.profileverification.target"
diff --git a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
index 4fbbfbb..2669001 100644
--- a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
+++ b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
@@ -130,7 +130,10 @@
}
} else {
try {
- mCurProfile.createNewFile();
+ if (!mCurProfile.createNewFile()) {
+ result(ProfileInstaller.RESULT_NOT_WRITABLE, null);
+ return false;
+ }
} catch (IOException e) {
// If the file cannot be created it's the same of the profile file not being
// writeable
@@ -139,7 +142,6 @@
}
}
-
mDeviceSupportsAotProfile = true;
return true;
}
diff --git a/room/room-common/api/api_lint.ignore b/room/room-common/api/api_lint.ignore
index a783aef..065bd1a 100644
--- a/room/room-common/api/api_lint.ignore
+++ b/room/room-common/api/api_lint.ignore
@@ -3,6 +3,20 @@
Acronyms should not be capitalized in class names: was `SQLiteTypeAffinity`, should this be `SqLiteTypeAffinity`?
+GetterSetterNames: field ColumnInfo.index:
+ Invalid name for boolean property `index`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Database.exportSchema:
+ Invalid name for boolean property `exportSchema`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Entity.inheritSuperIndices:
+ Invalid name for boolean property `inheritSuperIndices`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ForeignKey.deferred:
+ Invalid name for boolean property `deferred`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Index.unique:
+ Invalid name for boolean property `unique`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field PrimaryKey.autoGenerate:
+ Invalid name for boolean property `autoGenerate`. Should start with one of `has`, `can`, `should`, `is`.
+
+
PublicTypedef: androidx.room.ColumnInfo.Collate:
Don't expose @IntDef: Collate must be hidden.
PublicTypedef: androidx.room.ColumnInfo.SQLiteTypeAffinity:
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt
index c6f3ec1..77606d3 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/DefaultKspType.kt
@@ -25,8 +25,8 @@
internal class DefaultKspType(
env: KspProcessingEnv,
ksType: KSType,
- jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(env, ksType, jvmTypeResolver) {
+ scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope) {
override fun resolveJTypeName(): JTypeName {
// always box these. For primitives, typeName might return the primitive type but if we
@@ -46,15 +46,15 @@
return DefaultKspType(
env = env,
ksType = ksType.withNullability(nullability),
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return DefaultKspType(
env = env,
ksType = ksType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
index aa157d0..470c9af 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
@@ -18,6 +18,7 @@
import androidx.room.compiler.processing.XNullability
import com.google.devtools.ksp.symbol.KSAnnotated
+import com.google.devtools.ksp.symbol.KSAnnotation
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSNode
import com.google.devtools.ksp.symbol.KSType
@@ -57,19 +58,30 @@
else -> throw IllegalArgumentException("Cannot set KSType nullability to platform")
}
-private fun KSAnnotated.hasAnnotation(
- qName: String
- ) = annotations.any {
- it.annotationType.resolve().declaration.qualifiedName?.asString() == qName
- }
+private fun KSAnnotated.hasAnnotation(qName: String) =
+ annotations.any { it.hasQualifiedName(qName) }
- internal fun KSAnnotated.hasJvmWildcardAnnotation() = hasAnnotation(
- JvmWildcard::class.java.canonicalName!!
- )
+private fun KSAnnotation.hasQualifiedName(qName: String): Boolean {
+ return annotationType.resolve().hasQualifiedName(qName)
+}
- internal fun KSAnnotated.hasSuppressJvmWildcardAnnotation() = hasAnnotation(
- JvmSuppressWildcards::class.java.canonicalName!!
- )
+private fun KSType.hasQualifiedName(qName: String): Boolean {
+ return declaration.qualifiedName?.asString() == qName
+}
+
+internal fun KSAnnotated.hasJvmWildcardAnnotation() =
+ hasAnnotation(JvmWildcard::class.java.canonicalName!!)
+
+internal fun KSAnnotated.hasSuppressJvmWildcardAnnotation() =
+ hasAnnotation(JvmSuppressWildcards::class.java.canonicalName!!)
+
+private fun KSType.hasAnnotation(qName: String) = annotations.any { it.hasQualifiedName(qName) }
+
+internal fun KSType.hasJvmWildcardAnnotation() =
+ hasAnnotation(JvmWildcard::class.java.canonicalName!!)
+
+internal fun KSType.hasSuppressJvmWildcardAnnotation() =
+ hasAnnotation(JvmSuppressWildcards::class.java.canonicalName!!)
internal fun KSNode.hasSuppressWildcardsAnnotationInHierarchy(): Boolean {
(this as? KSAnnotated)?.let {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
index fa385e6..abada70 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
@@ -16,12 +16,13 @@
package androidx.room.compiler.processing.ksp
-import androidx.room.compiler.processing.ksp.KspArrayType.Companion.KOTLIN_ARRAY_Q_NAME
+import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.isOpen
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.KSTypeAlias
import com.google.devtools.ksp.symbol.KSTypeArgument
import com.google.devtools.ksp.symbol.KSTypeParameter
import com.google.devtools.ksp.symbol.Modifier
@@ -43,166 +44,323 @@
* Until then, the logic here is mostly reverse engineered from KAPT source code +
* KspTypeNamesGoldenTest ¯\_(ツ)_/¯
*/
-internal class KSTypeVarianceResolver(
- private val resolver: Resolver
-) {
+internal class KSTypeVarianceResolver(private val resolver: Resolver) {
/**
- * @param ksType The Kotlin type on which the variance will be applied
- * @param wildcardMode `wildcardMode` defines the default behavior of whether to inherit
- * variance or not. This depends on the existence of `SuppressWildcard` annotations or
- * the type's location (e.g. whether it is a method parameter or return type)
- * @param declarationType If a type is resolved via inheritance where it is not explicitly
- * declared in its container, this value should have its original type from the
- * declaration site. e.g. if you have `val BaseClass.x : T`, and the ksType is the
- * type of `x` from `SubClass: BaseClass<String>`, `declarationType` would be `T` whereas
- * the `ksType` is `String`. If the `ksType` is from the original declaration, this value
- * should be `null`.
+ * @param type The Kotlin type declared by the user on which the variance will be applied.
+ * @param scope The [KSTypeVarianceResolverScope] associated with the given type.
*/
- fun applyTypeVariance(
- ksType: KSType,
- wildcardMode: WildcardMode,
- declarationType: KSType?
- ): KSType = ksType.inheritVariance(declarationType, wildcardMode, ReferenceStack())
+ @OptIn(KspExperimental::class)
+ fun applyTypeVariance(type: KSType, scope: KSTypeVarianceResolverScope): KSType {
+ if (type.isError ||
+ type.arguments.isEmpty() ||
+ resolver.isJavaRawType(type) ||
+ !scope.needsWildcardResolution) {
+ // There's nothing to resolve in this case, so just return the original type.
+ return type
+ }
- /**
- * Update the variance of the arguments of this type based on the types declaration.
- *
- * For instance, in List<Foo>, it actually inherits the `out` variance from `List`.
- */
- private fun KSType.inheritVariance(
- declarationType: KSType?,
- wildcardMode: WildcardMode,
- referenceStack: ReferenceStack
+ val resolvedType = if (hasTypeVariables(scope.declarationType())) {
+ // If the associated declared type contains type variables that were resolved, e.g.
+ // using "asMemberOf", then it has special rules about how to resolve the types.
+ getJavaWildcardWithTypeVariables(
+ type = type,
+ declarationType = getJavaWildcard(scope.declarationType(), scope),
+ scope = scope,
+ )
+ } else {
+ getJavaWildcard(type, scope)
+ }
+
+ // As a final pass, we apply variance from any @JvmSuppressWildcards or @JvmWildcard
+ // annotations on the resolved type.
+ return applyJvmWildcardAnnotations(resolvedType)
+ }
+
+ private fun hasTypeVariables(
+ type: KSType?,
+ stack: ReferenceStack = ReferenceStack()
+ ): Boolean {
+ if (type == null || type.isError || stack.queue.contains(type)) {
+ return false
+ }
+ return stack.withReference(type) {
+ type.isTypeParameter() ||
+ type.arguments.any { hasTypeVariables(it.type?.resolve(), stack) }
+ }
+ }
+
+ private fun getJavaWildcard(
+ type: KSType,
+ scope: KSTypeVarianceResolverScope,
+ typeStack: ReferenceStack = ReferenceStack(),
+ typeArgStack: List<KSTypeArgument> = emptyList(),
+ typeParamStack: List<KSTypeParameter> = emptyList(),
): KSType {
- if (arguments.isEmpty()) return this
- return referenceStack.withReference(this) {
- // arrays don't inherit variance unless it is in an inherited method
- if (this.declaration.qualifiedName?.asString() == KOTLIN_ARRAY_Q_NAME &&
- declarationType == null
- ) {
- return@withReference this
- }
-
- // if we have type arguments but the declarationType doesn't, we should consider it like
- // star projection.
- // This happens when a given List<X> overrides T. In this case, we need to force X's
- // wildcards
- val starProject = declarationType != null && declarationType.arguments.isEmpty()
-
- // need to swap arguments with the variance from declaration
- val newArguments = arguments.mapIndexed { index, typeArg ->
- val param = declaration.typeParameters.getOrNull(index)
- val declarationArg = declarationType?.arguments?.getOrNull(index)
- val argWildcardMode = if (starProject) {
- WildcardMode.FORCED
- } else {
- wildcardMode
+ if (type.isError || typeStack.queue.contains(type)) {
+ return type
+ }
+ if (type.declaration is KSTypeAlias) {
+ return getJavaWildcard(
+ type = (type.declaration as KSTypeAlias).type.resolve(),
+ scope = scope,
+ typeStack = typeStack,
+ typeArgStack = typeArgStack,
+ typeParamStack = typeParamStack,
+ )
+ }
+ return typeStack.withReference(type) {
+ val resolvedTypeArgs =
+ type.arguments.indices.map { i ->
+ getJavaWildcard(
+ typeArg = type.arguments[i],
+ typeParam = type.declaration.typeParameters[i],
+ scope = scope,
+ typeStack = typeStack,
+ typeArgStack = typeArgStack,
+ typeParamStack = typeParamStack,
+ )
}
- typeArg.inheritVariance(declarationArg, argWildcardMode, param, referenceStack)
- }
- this.replace(newArguments)
+ type.replace(resolvedTypeArgs)
}
}
- private fun KSTypeArgument.inheritVariance(
- declarationType: KSTypeArgument?,
- wildcardMode: WildcardMode,
- param: KSTypeParameter?,
- referenceStack: ReferenceStack
+ private fun getJavaWildcard(
+ typeArg: KSTypeArgument,
+ typeParam: KSTypeParameter,
+ scope: KSTypeVarianceResolverScope,
+ typeStack: ReferenceStack,
+ typeArgStack: List<KSTypeArgument>,
+ typeParamStack: List<KSTypeParameter>,
): KSTypeArgument {
- if (param == null) {
- return this
+ val type = typeArg.type?.resolve()
+ if (
+ type == null ||
+ type.isError ||
+ typeArg.variance == Variance.STAR ||
+ typeStack.queue.contains(type)
+ ) {
+ return typeArg
}
- val myTypeRef = type ?: return this
-
- val myType = myTypeRef.resolve()
-
- if (referenceStack.contains(myType)) {
- // self referencing type
- return this
- }
- if (variance != Variance.INVARIANT) {
- return resolver.getTypeArgument(
- typeRef = myType.inheritVariance(
- declarationType?.type?.resolve(),
- wildcardMode,
- referenceStack
- ).createTypeReference(),
- variance = variance
- )
- }
-
- // Now we need to guess from this type. If the type is final, it does not inherit unless
- // the parameter is CONTRAVARIANT (`in`).
- val shouldInherit = when {
- hasJvmWildcardAnnotation() -> {
- // we actually don't need to check for wildcard annotation here as the TypeName
- // conversion will do it for the general case. Nevertheless, we check for it for
- // consistency
- true
+ val resolvedType = getJavaWildcard(
+ type = type,
+ scope = scope,
+ typeStack = typeStack,
+ typeArgStack = typeArgStack + typeArg,
+ typeParamStack = typeParamStack + typeParam
+ )
+ fun inheritDeclarationSiteVariance(): Boolean {
+ // Before we check the current variance, we need to check the previous variance in the
+ // stack to see if they allow us to inherit the current variance, and that logic differs
+ // depending on the scope.
+ if (scope.isValOrReturnType()) {
+ // For val and return type scopes, we don't use the declaration-site variance if
+ // none of variances in the stack are contravariant.
+ if (typeParamStack.indices.none { i ->
+ (typeParamStack[i].variance == Variance.CONTRAVARIANT ||
+ typeArgStack[i].variance == Variance.CONTRAVARIANT) &&
+ // The declaration and use site variance is ignored when using @JvmWildcard
+ // explicitly on a type.
+ !typeArgStack[i].hasJvmWildcardAnnotation()
+ }) {
+ return false
+ }
+ } else {
+ // For method parameters and var type scopes, we don't use the declaration-site
+ // variance if the last variance in the declaration-site stack was invariant and
+ // the last variance in the use-site stack was not contravariant.
+ if (typeParamStack.lastOrNull()?.variance == Variance.INVARIANT &&
+ typeArgStack.lastOrNull()?.variance != Variance.CONTRAVARIANT) {
+ return false
+ }
}
- wildcardMode == WildcardMode.SUPPRESSED -> false
- wildcardMode == WildcardMode.FORCED -> true
- hasSuppressWildcardsAnnotationInHierarchy() -> false
- else -> {
- if (declarationType != null) {
- // if there is a declaration type, that means we are being resolved for an
- // inherited method/property; hence we should use the variance in the
- // declaration
- true
- } else {
- param.variance == Variance.CONTRAVARIANT ||
- when (val decl = myType.declaration) {
- is KSClassDeclaration -> {
- decl.isOpen() || decl.classKind == ClassKind.ENUM_CLASS ||
- decl.modifiers.contains(Modifier.SEALED)
- }
- else -> true
+ return when (typeParam.variance) {
+ // If the current declaration-site variance is invariant then don't inherit it.
+ Variance.INVARIANT -> false
+ // If the current declaration-site variance is contravariant then inherit it.
+ Variance.CONTRAVARIANT -> true
+ // If the current declaration-site variance is covariant then inherit it unless
+ // it's a final class (excluding enum/sealed classes).
+ Variance.COVARIANT -> when (val declaration = type.declaration) {
+ is KSClassDeclaration -> declaration.isOpen() ||
+ declaration.classKind == ClassKind.ENUM_CLASS ||
+ declaration.modifiers.contains(Modifier.SEALED) ||
+ // For non-open/enum/sealed classes we may still decided to use the
+ // declaration-site variance based on if any of the type arguments in the
+ // resolved type has variance and the use-site variance is not equal to
+ // covariant/contravariant.
+ resolvedType.arguments.indices.any { i ->
+ resolvedType.arguments[i].variance != Variance.INVARIANT &&
+ type.arguments[i].variance != Variance.COVARIANT &&
+ type.arguments[i].variance != Variance.CONTRAVARIANT
}
+ else -> true
+ }
+ Variance.STAR -> error {
+ "Declaration site variance was not expected to contain STAR: $typeParam."
}
}
}
- val newVariance = if (declarationType?.variance == Variance.STAR) {
- Variance.COVARIANT
- } else if (declarationType?.type?.resolve() is KSTypeParameter) {
- // fallback to the parameter variance if we are swapping a type parameter type
- param.variance
+ val resolvedVariance = if (inheritDeclarationSiteVariance()) {
+ typeParam.variance
+ } else if (typeParam.variance == typeArg.variance) {
+ // If we're not applying the declaration-site variance, and the use-site variance is the
+ // same as the declaration-site variance then we don't include the use-site variance in
+ // the jvm type either.
+ Variance.INVARIANT
} else {
- declarationType?.variance
- } ?: param.variance
- return if (shouldInherit) {
- resolver.getTypeArgument(
- typeRef = myType.inheritVariance(
- declarationType?.type?.resolve(),
- wildcardMode,
- referenceStack
- ).createTypeReference(),
- variance = newVariance
- )
- } else {
- resolver.getTypeArgument(
- typeRef = myType.inheritVariance(null, wildcardMode, referenceStack)
- .createTypeReference(),
- variance = variance
- )
+ typeArg.variance
+ }
+ return createTypeArgument(resolvedType, resolvedVariance)
+ }
+
+ private fun getJavaWildcardWithTypeVariables(
+ type: KSType,
+ declarationType: KSType? = null,
+ scope: KSTypeVarianceResolverScope,
+ typeStack: ReferenceStack = ReferenceStack(),
+ ): KSType {
+ if (type.isError || typeStack.queue.contains(type)) {
+ return type
+ }
+ return typeStack.withReference(type) {
+ val resolvedTypeArgs =
+ if (declarationType != null && !declarationType.isTypeParameter()) {
+ declarationType.arguments.indices.map { i ->
+ getJavaWildcardWithTypeVariablesForOuterType(
+ typeArg = type.arguments[i],
+ declarationTypeArg = declarationType.arguments[i],
+ scope = scope,
+ typeStack = typeStack,
+ )
+ }
+ } else {
+ type.arguments.indices.map { i ->
+ getJavaWildcardWithTypeVariablesForInnerType(
+ typeArg = type.arguments[i],
+ declarationTypeParameter = type.declaration.typeParameters[i],
+ scope = scope,
+ typeStack = typeStack,
+ )
+ }
+ }
+ type.replace(resolvedTypeArgs)
}
}
- enum class WildcardMode {
- /**
- * Force wildcard inheritance that is commonly used when there is star projection involved
- */
- FORCED,
+ private fun getJavaWildcardWithTypeVariablesForInnerType(
+ typeArg: KSTypeArgument,
+ declarationTypeParameter: KSTypeParameter,
+ scope: KSTypeVarianceResolverScope,
+ typeStack: ReferenceStack,
+ ): KSTypeArgument {
+ val type = typeArg.type?.resolve()
+ if (
+ type == null ||
+ type.isError ||
+ typeArg.variance == Variance.STAR ||
+ typeStack.queue.contains(type)
+ ) {
+ return typeArg
+ }
+ val resolvedType = getJavaWildcardWithTypeVariables(
+ type = type,
+ scope = scope,
+ typeStack = typeStack,
+ )
+ val resolvedVariance = if (declarationTypeParameter.variance != Variance.INVARIANT) {
+ declarationTypeParameter.variance
+ } else {
+ typeArg.variance
+ }
+ return createTypeArgument(resolvedType, resolvedVariance)
+ }
- /**
- * Apply wildcard inheritance when necessary.
- */
- PREFERRED,
+ private fun getJavaWildcardWithTypeVariablesForOuterType(
+ typeArg: KSTypeArgument,
+ declarationTypeArg: KSTypeArgument,
+ scope: KSTypeVarianceResolverScope,
+ typeStack: ReferenceStack,
+ ): KSTypeArgument {
+ val type = typeArg.type?.resolve()
+ if (
+ type == null ||
+ type.isError ||
+ typeArg.variance == Variance.STAR ||
+ typeStack.queue.contains(type)
+ ) {
+ return typeArg
+ }
+ val resolvedType = getJavaWildcardWithTypeVariables(
+ type = type,
+ declarationType = declarationTypeArg.type?.resolve(),
+ scope = scope,
+ typeStack = typeStack
+ )
+ val resolvedVariance = if (declarationTypeArg.variance != Variance.INVARIANT &&
+ (!scope.isValOrReturnType() || declarationTypeArg.variance != Variance.COVARIANT)) {
+ declarationTypeArg.variance
+ } else {
+ typeArg.variance
+ }
+ return createTypeArgument(resolvedType, resolvedVariance)
+ }
- /**
- * Apply wildcard inheritance only if it is explicitly stated with JvmWildcards annotation.
- */
- SUPPRESSED
+ private fun applyJvmWildcardAnnotations(
+ type: KSType,
+ typeStack: ReferenceStack = ReferenceStack(),
+ ): KSType {
+ if (type.isError || typeStack.queue.contains(type)) {
+ return type
+ }
+ return typeStack.withReference(type) {
+ val resolvedTypeArgs =
+ type.arguments.indices.map { i ->
+ applyJvmWildcardAnnotations(
+ typeArg = type.arguments[i],
+ typeParameter = type.declaration.typeParameters[i],
+ typeStack = typeStack,
+ )
+ }
+ type.replace(resolvedTypeArgs)
+ }
+ }
+
+ private fun applyJvmWildcardAnnotations(
+ typeArg: KSTypeArgument,
+ typeParameter: KSTypeParameter,
+ typeStack: ReferenceStack,
+ ): KSTypeArgument {
+ val type = typeArg.type?.resolve()
+ if (
+ type == null ||
+ type.isError ||
+ typeArg.variance == Variance.STAR ||
+ typeStack.queue.contains(type)
+ ) {
+ return typeArg
+ }
+ val resolvedType = applyJvmWildcardAnnotations(
+ type = type,
+ typeStack = typeStack,
+ )
+ val resolvedVariance = when {
+ typeParameter.variance == Variance.INVARIANT &&
+ typeArg.variance != Variance.INVARIANT -> typeArg.variance
+ typeArg.hasJvmWildcardAnnotation() -> typeParameter.variance
+ typeStack.queue.any { it.hasSuppressJvmWildcardAnnotation() } ||
+ typeArg.hasSuppressWildcardsAnnotationInHierarchy() ||
+ typeParameter.hasSuppressWildcardsAnnotationInHierarchy() -> Variance.INVARIANT
+ else -> typeArg.variance
+ }
+ return createTypeArgument(resolvedType, resolvedVariance)
+ }
+
+ private fun KSType.isTypeParameter(): Boolean {
+ return createTypeReference().isTypeParameterReference()
+ }
+
+ private fun createTypeArgument(type: KSType, variance: Variance): KSTypeArgument {
+ return resolver.getTypeArgument(type.createTypeReference(), variance)
}
}
@@ -212,20 +370,17 @@
* if a type argument resolves to it, it will stop recursion.
*/
private class ReferenceStack {
- @Suppress("PropertyName")
- val _queue = ArrayDeque<KSType>()
-
- fun contains(ksType: KSType) = _queue.contains(ksType)
+ val queue = ArrayDeque<KSType>()
inline fun <T> withReference(
ksType: KSType,
crossinline block: () -> T
): T {
return try {
- _queue.addLast(ksType)
+ queue.addLast(ksType)
block()
} finally {
- _queue.removeLast()
+ queue.removeLast()
}
}
-}
\ No newline at end of file
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
new file mode 100644
index 0000000..9b4c646
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.room.compiler.processing.ksp
+
+import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
+import com.google.devtools.ksp.symbol.KSAnnotated
+import com.google.devtools.ksp.symbol.KSDeclaration
+import com.google.devtools.ksp.symbol.KSNode
+import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.Origin
+
+/**
+ * Provides KSType resolution scope for a type.
+ */
+internal sealed class KSTypeVarianceResolverScope(
+ private val annotated: KSAnnotated,
+ private val container: KSDeclaration?
+) {
+ /**
+ * Checks whether we need wildcard resolution at all. It is only necessary if either the method
+ * parameter is in kotlin or the containing class, which inherited the method, is in kotlin.
+ */
+ val needsWildcardResolution: Boolean by lazy {
+ (annotated.isInKotlinCode() || container?.isInKotlinCode() == true) &&
+ !annotated.hasSuppressWildcardsAnnotationInHierarchy()
+ }
+
+ private fun KSAnnotated.isInKotlinCode(): Boolean {
+ // find the true origin by skipping synthetics.
+ var current: KSNode? = this
+ while (current != null) {
+ val origin = current.origin
+ if (origin != Origin.SYNTHETIC) {
+ return origin == Origin.KOTLIN || origin == Origin.KOTLIN_LIB
+ }
+ current = current.parent
+ }
+ return false
+ }
+
+ /** Finds the [KSType] from the declaration. */
+ abstract fun declarationType(): KSType
+
+ /** Returns `true` if this scope represents a val property or a return type. */
+ abstract fun isValOrReturnType(): Boolean
+
+ internal class MethodParameter(
+ private val kspExecutableElement: KspExecutableElement,
+ private val parameterIndex: Int,
+ annotated: KSAnnotated,
+ container: KSDeclaration?,
+ ) : KSTypeVarianceResolverScope(annotated, container) {
+ override fun declarationType() =
+ (kspExecutableElement.parameters[parameterIndex].type as KspType).ksType
+
+ override fun isValOrReturnType() = false
+ }
+
+ internal class PropertySetterParameterType(
+ private val setterMethod: KspSyntheticPropertyMethodElement.Setter
+ ) : KSTypeVarianceResolverScope(
+ annotated = setterMethod.accessor,
+ container = setterMethod.field.enclosingElement.declaration
+ ) {
+ override fun declarationType(): KSType {
+ // We return the declaration from the setter, not the field because the setter parameter
+ // will have a different type in jvm (due to jvm wildcard resolution)
+ return (setterMethod.field.syntheticSetter!!.parameters.single().type as KspType).ksType
+ }
+
+ override fun isValOrReturnType() = false
+ }
+
+ internal class PropertyGetterMethodReturnType(
+ private val getterMethod: KspSyntheticPropertyMethodElement.Getter
+ ) : KSTypeVarianceResolverScope(
+ annotated = getterMethod.accessor,
+ container = getterMethod.field.enclosingElement.declaration
+ ) {
+ override fun declarationType(): KSType {
+ // We return the declaration from the getter, not the field because the getter return
+ // type will have a different type in jvm (due to jvm wildcard resolution)
+ return (getterMethod.field.syntheticAccessors.first().returnType as KspType).ksType
+ }
+
+ override fun isValOrReturnType() = true
+ }
+
+ internal class PropertyType(val field: KspFieldElement) : KSTypeVarianceResolverScope(
+ annotated = field.declaration,
+ container = field.enclosingElement.declaration
+ ) {
+ override fun declarationType() = field.type.ksType
+
+ override fun isValOrReturnType() = field.isFinal()
+ }
+
+ internal class MethodReturnType(val method: KspMethodElement) : KSTypeVarianceResolverScope(
+ annotated = method.declaration,
+ container = method.enclosingElement.declaration
+ ) {
+ override fun declarationType() = method.returnType.ksType
+
+ override fun isValOrReturnType() = true
+ }
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt
index a787112..21a2942 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspArrayType.kt
@@ -17,7 +17,6 @@
package androidx.room.compiler.processing.ksp
import androidx.room.compiler.codegen.JArrayTypeName
-import androidx.room.compiler.codegen.XTypeName
import androidx.room.compiler.processing.XArrayType
import androidx.room.compiler.processing.XNullability
import androidx.room.compiler.processing.XType
@@ -29,11 +28,8 @@
internal sealed class KspArrayType(
env: KspProcessingEnv,
ksType: KSType,
- jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(
- env, ksType, jvmTypeResolver
-),
- XArrayType {
+ scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope), XArrayType {
abstract override val componentType: KspType
@@ -56,20 +52,15 @@
private class BoxedArray(
env: KspProcessingEnv,
ksType: KSType,
- jvmTypeResolver: KspJvmTypeResolver?
- ) : KspArrayType(
- env, ksType, jvmTypeResolver
- ) {
- private val xTypeName: XTypeName by lazy {
- val componentTypeName = componentType.asTypeName()
- XTypeName(
- java = JArrayTypeName.of(componentTypeName.java.box()),
- kotlin = ksType.asKTypeName(env.resolver),
- nullability = nullability,
- )
+ scope: KSTypeVarianceResolverScope?
+ ) : KspArrayType(env, ksType, scope) {
+ override fun resolveJTypeName(): JTypeName {
+ return JArrayTypeName.of(componentType.asTypeName().java.box())
}
- override fun asTypeName() = xTypeName
+ override fun resolveKTypeName(): KTypeName {
+ return ksType.asKTypeName(env.resolver)
+ }
override val componentType: KspType by lazy {
val arg = ksType.arguments.single()
@@ -85,15 +76,15 @@
return BoxedArray(
env = env,
ksType = ksType.withNullability(nullability),
- jvmTypeResolver = jvmTypeResolver,
+ scope = scope,
)
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return BoxedArray(
env = env,
ksType = ksType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
@@ -104,37 +95,32 @@
private class PrimitiveArray(
env: KspProcessingEnv,
ksType: KSType,
- jvmTypeResolver: KspJvmTypeResolver?,
+ scope: KSTypeVarianceResolverScope?,
override val componentType: KspType
- ) : KspArrayType(
- env, ksType, jvmTypeResolver
- ) {
- private val xTypeName: XTypeName by lazy {
- val componentTypeName = componentType.asTypeName()
- XTypeName(
- java = JArrayTypeName.of(componentTypeName.java.unbox()),
- kotlin = ksType.asKTypeName(env.resolver),
- nullability = nullability,
- )
+ ) : KspArrayType(env, ksType, scope) {
+ override fun resolveJTypeName(): JTypeName {
+ return JArrayTypeName.of(componentType.asTypeName().java.unbox())
}
- override fun asTypeName() = xTypeName
+ override fun resolveKTypeName(): KTypeName {
+ return ksType.asKTypeName(env.resolver)
+ }
override fun copyWithNullability(nullability: XNullability): PrimitiveArray {
return PrimitiveArray(
env = env,
ksType = ksType.withNullability(nullability),
componentType = componentType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return PrimitiveArray(
env = env,
ksType = ksType,
componentType = componentType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
@@ -170,7 +156,7 @@
primitiveArrayEntry.key
),
componentType = primitiveArrayEntry.value,
- jvmTypeResolver = null
+ scope = null
)
}
}
@@ -185,7 +171,7 @@
)
)
),
- jvmTypeResolver = null
+ scope = null
)
}
@@ -199,7 +185,7 @@
return BoxedArray(
env = env,
ksType = ksType,
- jvmTypeResolver = null
+ scope = null
)
}
builtInArrays[qName]?.let { primitiveType ->
@@ -207,7 +193,7 @@
env = env,
ksType = ksType,
componentType = primitiveType,
- jvmTypeResolver = null
+ scope = null
)
}
return null
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
index fe11246..84cf572 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
@@ -22,7 +22,6 @@
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_METHOD_PARAMETER
import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
-import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.google.devtools.ksp.symbol.KSPropertySetter
import com.google.devtools.ksp.symbol.KSType
@@ -48,15 +47,6 @@
override val hasDefaultValue: Boolean
get() = parameter.hasDefault
- private fun jvmTypeResolver(container: KSDeclaration?): KspJvmTypeResolutionScope {
- return KspJvmTypeResolutionScope.MethodParameter(
- kspExecutableElement = enclosingElement,
- parameterIndex = parameterIndex,
- annotated = parameter.type,
- container = container
- )
- }
-
override val type: KspType by lazy {
asMemberOf(enclosingElement.enclosingElement.type?.ksType)
}
@@ -83,8 +73,11 @@
functionDeclaration = enclosingElement.declaration,
ksType = ksType
)
- ).withJvmTypeResolver(
- jvmTypeResolver(
+ ).copyWithScope(
+ KSTypeVarianceResolverScope.MethodParameter(
+ kspExecutableElement = enclosingElement,
+ parameterIndex = parameterIndex,
+ annotated = parameter.type,
container = ksType?.declaration
)
)
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
index 6963639..b8bad187 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
@@ -103,7 +103,7 @@
return env.wrap(
originatingReference = declaration.type,
ksType = declaration.typeAsMemberOf(ksType)
- )
+ ).copyWithScope(KSTypeVarianceResolverScope.PropertyType(this))
}
companion object {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspJvmTypeResolver.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspJvmTypeResolver.kt
deleted file mode 100644
index ba92d38..0000000
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspJvmTypeResolver.kt
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.room.compiler.processing.ksp
-
-import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
-import com.google.devtools.ksp.symbol.KSAnnotated
-import com.google.devtools.ksp.symbol.KSDeclaration
-import com.google.devtools.ksp.symbol.KSNode
-import com.google.devtools.ksp.symbol.Origin
-
-/**
- * JvmType of a Kotlin type depends on where the type is declared.
- *
- * This resolver is used to resolve that type when necessary (computing TypeName).
- * See [KSTypeVarianceResolver] for details.
- */
-internal class KspJvmTypeResolver(
- val scope: KspJvmTypeResolutionScope,
- val delegate: KspType
-) {
- internal fun resolveJvmType(
- env: KspProcessingEnv
- ): KspType {
- if (!scope.needsWildcardResolution) {
- return delegate
- }
- val wildcardMode = if (scope.suppressesWildcards) {
- KSTypeVarianceResolver.WildcardMode.SUPPRESSED
- } else {
- KSTypeVarianceResolver.WildcardMode.PREFERRED
- }
-
- val declarationType = scope.findDeclarationType() as? KspType
- return env.resolveWildcards(
- ksType = delegate.ksType,
- wildcardMode = wildcardMode,
- // See KSTypeVarianceResolver#applyTypeVariance: "If the ksType is from the original
- // declaration, declarationType should be null".
- declarationType = if (declarationType == delegate) {
- null
- } else {
- // use the jvm type of the declaration so that it also gets its jvm wildcards
- // resolved.
- declarationType?.jvmWildcardTypeOrSelf?.ksType
- }
- ).let {
- env.wrap(
- ksType = it,
- allowPrimitives = delegate is KspPrimitiveType
- )
- }
- }
-}
-
-/**
- * Provides KSType resolution scope for parameter types.
- */
-internal sealed class KspJvmTypeResolutionScope(
- private val annotated: KSAnnotated,
- private val container: KSDeclaration?
-) {
- /**
- * Checks whether we need wildcard resolution at all. It is only necessary if either the method
- * parameter is in kotlin or the containing class, which inherited the method, is in kotlin.
- */
- val needsWildcardResolution: Boolean by lazy {
- annotated.isInKotlinCode() || container?.isInKotlinCode() == true
- }
-
- /**
- * Checks if the wildcards are suppressed by checking the hierarchy of the declaration to see if
- * it has the @JvmSuppressWildcards annotation.
- */
- val suppressesWildcards by lazy {
- // suppress wildcards depend on the declaration site.
- annotated.hasSuppressWildcardsAnnotationInHierarchy()
- }
-
- private fun KSAnnotated.isInKotlinCode(): Boolean {
- // find the true origin by skipping synthetics.
- var current: KSNode? = this
- while (current != null) {
- val origin = current.origin
- if (origin != Origin.SYNTHETIC) {
- return origin == Origin.KOTLIN || origin == Origin.KOTLIN_LIB
- }
- current = current.parent
- }
- return false
- }
-
- /**
- * Finds the XType from the declaration if and only if this method is inherited from another
- * class / interface.
- */
- abstract fun findDeclarationType(): XType?
-
- internal class MethodParameter(
- private val kspExecutableElement: KspExecutableElement,
- private val parameterIndex: Int,
- annotated: KSAnnotated,
- container: KSDeclaration?,
- ) : KspJvmTypeResolutionScope(annotated, container) {
- override fun findDeclarationType(): XType? {
- return if (kspExecutableElement is KspMethodElement) {
- kspExecutableElement.executableType.parameterTypes.getOrNull(parameterIndex)
- } else {
- null
- }
- }
- }
-
- internal class PropertySetterParameter(
- val declaration: KspSyntheticPropertyMethodElement
- ) : KspJvmTypeResolutionScope(
- annotated = declaration.accessor,
- container = declaration.field.enclosingElement.declaration
- ) {
- override fun findDeclarationType(): XType? {
- // We return the declaration from the setter, not the field because the setter parameter
- // will have a different type in jvm (due to jvm wildcard resolution)
- return declaration.field.syntheticSetter?.parameters?.firstOrNull()?.type
- }
- }
-}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
index 4d06d47..131b645 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
@@ -112,15 +112,17 @@
override fun isKotlinPropertyMethod() = false
+ abstract override val returnType: KspType
+
private class KspNormalMethodElement(
env: KspProcessingEnv,
declaration: KSFunctionDeclaration
) : KspMethodElement(env, declaration) {
- override val returnType: XType by lazy {
+ override val returnType: KspType by lazy {
declaration.returnKspType(
env = env,
containing = enclosingElement.type
- )
+ ).copyWithScope(KSTypeVarianceResolverScope.MethodReturnType(this))
}
override fun isSuspendFunction() = false
}
@@ -131,11 +133,11 @@
) : KspMethodElement(env, declaration) {
override fun isSuspendFunction() = true
- override val returnType: XType by lazy {
+ override val returnType: KspType by lazy {
env.wrap(
ksType = env.resolver.builtIns.anyType.makeNullable(),
allowPrimitives = false
- )
+ ).copyWithScope(KSTypeVarianceResolverScope.MethodReturnType(this))
}
override val parameters: List<XExecutableParameterElement>
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
index ec72704..fba2cbc 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
@@ -47,7 +47,7 @@
origin.declaration.returnKspType(
env = env,
containing = containing
- )
+ ).copyWithScope(KSTypeVarianceResolverScope.MethodReturnType(origin))
}
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
index 771dba1..73d675c 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
@@ -32,8 +32,8 @@
internal class KspPrimitiveType(
env: KspProcessingEnv,
ksType: KSType,
- jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(env, ksType, jvmTypeResolver) {
+ scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope) {
override fun resolveJTypeName(): JTypeName {
return ksType.asJTypeName(env.resolver).tryUnbox()
}
@@ -66,11 +66,11 @@
}
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return KspPrimitiveType(
env = env,
ksType = ksType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
index 232bacd..acf2615 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
@@ -105,7 +105,7 @@
env = this,
ksType = resolver.builtIns.unitType,
boxed = false,
- jvmTypeResolver = null
+ scope = null
)
override fun findTypeElement(qName: String): KspTypeElement? {
@@ -227,7 +227,7 @@
return KspTypeArgumentType(
env = this,
typeArg = ksTypeArgument,
- jvmTypeResolver = null
+ scope = null
)
}
@@ -258,14 +258,14 @@
return KspTypeVariableType(
env = this,
ksType = ksType,
- jvmTypeResolver = null
+ scope = null
)
}
if (allowPrimitives && qName != null && ksType.nullability == Nullability.NOT_NULL) {
// check for primitives
val javaPrimitive = KspTypeMapper.getPrimitiveJavaTypeName(qName)
if (javaPrimitive != null) {
- return KspPrimitiveType(this, ksType, jvmTypeResolver = null)
+ return KspPrimitiveType(this, ksType, scope = null)
}
// special case for void
if (qName == "kotlin.Unit") {
@@ -275,7 +275,7 @@
return arrayTypeFactory.createIfArray(ksType) ?: DefaultKspType(
this,
ksType,
- jvmTypeResolver = null
+ scope = null
)
}
@@ -295,26 +295,8 @@
/**
* Resolves the wildcards for the given ksType. See [KSTypeVarianceResolver] for details.
*/
- fun resolveWildcards(
- /**
- * The KSType whose wildcards variance will be resolved
- */
- ksType: KSType,
- /**
- * Default wildcard resolution strategy
- */
- wildcardMode: KSTypeVarianceResolver.WildcardMode,
- /**
- * The original declaration type if [ksType] is obtained via inheritance.
- */
- declarationType: KSType?
- ): KSType {
- return ksTypeVarianceResolver.applyTypeVariance(
- ksType = ksType,
- wildcardMode = wildcardMode,
- declarationType = declarationType
- )
- }
+ internal fun resolveWildcards(ksType: KSType, scope: KSTypeVarianceResolverScope) =
+ ksTypeVarianceResolver.applyTypeVariance(ksType, scope)
internal fun clearCache() {
typeElementStore.clear()
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
index d6b75dd..8fc4f16 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
@@ -52,7 +52,7 @@
/**
* Type resolver to convert KSType into its JVM representation.
*/
- protected val jvmTypeResolver: KspJvmTypeResolver?
+ protected val scope: KSTypeVarianceResolverScope?
) : KspAnnotated(env), XType, XEquality {
override val rawType by lazy {
KspRawType(this)
@@ -62,27 +62,34 @@
xTypeName.java
}
- private val xTypeName: XTypeName by lazy {
- XTypeName(
- jvmWildcardType?.asTypeName()?.java ?: resolveJTypeName(),
- jvmWildcardType?.asTypeName()?.kotlin ?: resolveKTypeName(),
- nullability
- )
- }
-
override fun asTypeName() = xTypeName
/**
- * A Kotlin type might have a slightly different type in JVM due to wildcards.
- * This fields holds onto that value which will be used when creating JVM types.
+ * A Kotlin type might have a slightly different type in JVM vs Kotlin due to wildcards.
+ * The [XTypeName] represents those differences as [JTypeName] and [KTypeName], respectively.
*/
- private val jvmWildcardType by lazy {
- jvmTypeResolver?.resolveJvmType(env)
+ private val xTypeName: XTypeName by lazy {
+ val jvmWildcardType = if (scope == null) {
+ this
+ } else {
+ env.resolveWildcards(ksType, scope).let {
+ if (it == ksType) {
+ this
+ } else {
+ env.wrap(
+ ksType = it,
+ allowPrimitives = this is KspPrimitiveType
+ ).copyWithScope(scope)
+ }
+ }
+ }
+ XTypeName(
+ jvmWildcardType.resolveJTypeName(),
+ jvmWildcardType.resolveKTypeName(),
+ nullability
+ )
}
- internal val jvmWildcardTypeOrSelf
- get() = jvmWildcardType ?: this
-
protected abstract fun resolveJTypeName(): JTypeName
protected abstract fun resolveKTypeName(): KTypeName
@@ -266,20 +273,7 @@
abstract override fun boxed(): KspType
- fun withJvmTypeResolver(
- jvmTypeResolver: KspJvmTypeResolutionScope
- ): KspType {
- return copyWithJvmTypeResolver(
- KspJvmTypeResolver(
- scope = jvmTypeResolver,
- delegate = this
- )
- )
- }
-
- abstract fun copyWithJvmTypeResolver(
- jvmTypeResolver: KspJvmTypeResolver
- ): KspType
+ abstract fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType
/**
* Create a copy of this type with the given nullability.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
index ffacdbd..7593b7f 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
@@ -31,11 +31,11 @@
internal class KspTypeArgumentType(
env: KspProcessingEnv,
val typeArg: KSTypeArgument,
- jvmTypeResolver: KspJvmTypeResolver?
+ scope: KSTypeVarianceResolverScope?
) : KspType(
env = env,
ksType = typeArg.requireType(),
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
) {
/**
* When KSP resolves classes, it always resolves to the upper bound. Hence, the ksType we
@@ -77,15 +77,15 @@
original = typeArg,
type = ksType.withNullability(nullability).createTypeReference()
),
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return KspTypeArgumentType(
env = env,
typeArg = typeArg,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt
index 9d91f0c4..cd2b9e6 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeVariableType.kt
@@ -27,12 +27,8 @@
internal class KspTypeVariableType(
env: KspProcessingEnv,
ksType: KSType,
- jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(
- env = env,
- ksType = ksType,
- jvmTypeResolver = jvmTypeResolver
-), XTypeVariableType {
+ scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope), XTypeVariableType {
private val typeVariable: KSTypeParameter by lazy {
// Note: This is a workaround for a bug in KSP where we may get ERROR_TYPE in the bounds
// (https://github.com/google/ksp/issues/1250). To work around it we get the matching
@@ -60,15 +56,15 @@
return KspTypeVariableType(
env = env,
ksType = ksType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return KspTypeVariableType(
env = env,
ksType = ksType,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt
index 87d50ca..a68b298 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspVoidType.kt
@@ -32,8 +32,8 @@
env: KspProcessingEnv,
ksType: KSType,
val boxed: Boolean,
- jvmTypeResolver: KspJvmTypeResolver?
-) : KspType(env, ksType, jvmTypeResolver) {
+ scope: KSTypeVarianceResolverScope?
+) : KspType(env, ksType, scope) {
override fun resolveJTypeName(): JTypeName {
return if (boxed || nullability == XNullability.NULLABLE) {
JTypeName.VOID.box()
@@ -54,7 +54,7 @@
env = env,
ksType = ksType,
boxed = true,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
@@ -64,16 +64,16 @@
env = env,
ksType = ksType.withNullability(nullability),
boxed = boxed || nullability == XNullability.NULLABLE,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
- override fun copyWithJvmTypeResolver(jvmTypeResolver: KspJvmTypeResolver): KspType {
+ override fun copyWithScope(scope: KSTypeVarianceResolverScope): KspType {
return KspVoidType(
env = env,
ksType = ksType,
boxed = boxed,
- jvmTypeResolver = jvmTypeResolver
+ scope = scope
)
}
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
index 66b4c84..1fbc669 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
@@ -21,16 +21,15 @@
import androidx.room.compiler.processing.XExecutableParameterElement
import androidx.room.compiler.processing.XMemberContainer
import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
import androidx.room.compiler.processing.ksp.KspAnnotated
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE
-import androidx.room.compiler.processing.ksp.KspJvmTypeResolutionScope
import androidx.room.compiler.processing.ksp.KspMethodElement
import androidx.room.compiler.processing.ksp.KspProcessingEnv
import androidx.room.compiler.processing.ksp.KspType
import androidx.room.compiler.processing.ksp.requireContinuationClass
import androidx.room.compiler.processing.ksp.returnTypeAsMemberOf
import androidx.room.compiler.processing.ksp.swapResolvedType
-import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.Variance
@@ -75,15 +74,6 @@
override val hasDefaultValue: Boolean
get() = false
- private fun jvmTypeResolutionScope(container: KSDeclaration?): KspJvmTypeResolutionScope {
- return KspJvmTypeResolutionScope.MethodParameter(
- kspExecutableElement = enclosingElement,
- parameterIndex = enclosingElement.parameters.size - 1,
- annotated = enclosingElement.declaration,
- container = container
- )
- }
-
override val type: KspType by lazy {
asMemberOf(enclosingElement.enclosingElement.type?.ksType)
}
@@ -124,8 +114,11 @@
return env.wrap(
ksType = contType,
allowPrimitives = false
- ).withJvmTypeResolver(
- jvmTypeResolutionScope(
+ ).copyWithScope(
+ KSTypeVarianceResolverScope.MethodParameter(
+ kspExecutableElement = enclosingElement,
+ parameterIndex = enclosingElement.parameters.size - 1,
+ annotated = enclosingElement.declaration,
container = ksType?.declaration
)
)
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
index ec5190d..b5e1a70 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
@@ -27,13 +27,13 @@
import androidx.room.compiler.processing.XTypeElement
import androidx.room.compiler.processing.XTypeParameterElement
import androidx.room.compiler.processing.javac.kotlin.JvmAbi
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
import androidx.room.compiler.processing.ksp.KspAnnotated
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_GETTER
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_SETTER
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_SET_PARAM
import androidx.room.compiler.processing.ksp.KspFieldElement
import androidx.room.compiler.processing.ksp.KspHasModifiers
-import androidx.room.compiler.processing.ksp.KspJvmTypeResolutionScope
import androidx.room.compiler.processing.ksp.KspProcessingEnv
import androidx.room.compiler.processing.ksp.KspType
import androidx.room.compiler.processing.ksp.findEnclosingMemberContainer
@@ -144,7 +144,7 @@
override fun isKotlinPropertyMethod() = true
- private class Getter(
+ internal class Getter(
env: KspProcessingEnv,
field: KspFieldElement,
override val accessor: KSPropertyGetter
@@ -167,7 +167,9 @@
get() = this.jvmDescriptor()
override val returnType: XType by lazy {
- field.type
+ field.type.copyWithScope(
+ KSTypeVarianceResolverScope.PropertyGetterMethodReturnType(this)
+ )
}
override val typeParameters: List<XTypeParameterElement>
@@ -181,7 +183,7 @@
}
}
- private class Setter(
+ internal class Setter(
env: KspProcessingEnv,
field: KspFieldElement,
override val accessor: KSPropertySetter
@@ -238,18 +240,14 @@
override fun isKotlinPropertyParam() = true
- private val jvmTypeResolutionScope = KspJvmTypeResolutionScope.PropertySetterParameter(
- declaration = enclosingElement
- )
-
override val name: String by lazy {
val originalName = enclosingElement.accessor.parameter.name?.asString()
originalName.sanitizeAsJavaParameterName(0)
}
override val type: KspType by lazy {
- enclosingElement.field.type.withJvmTypeResolver(
- jvmTypeResolutionScope
+ enclosingElement.field.type.copyWithScope(
+ KSTypeVarianceResolverScope.PropertySetterParameterType(enclosingElement)
)
}
@@ -265,7 +263,9 @@
override fun asMemberOf(other: XType): KspType {
return enclosingElement.field.asMemberOf(other)
- .withJvmTypeResolver(jvmTypeResolutionScope)
+ .copyWithScope(
+ KSTypeVarianceResolverScope.PropertySetterParameterType(enclosingElement)
+ )
}
override val docComment: String?
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
index e2221aa..a482093 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
@@ -19,6 +19,7 @@
import androidx.room.compiler.processing.XExecutableType
import androidx.room.compiler.processing.XMethodType
import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
import androidx.room.compiler.processing.ksp.KspProcessingEnv
import com.google.devtools.ksp.symbol.KSPropertyGetter
import com.google.devtools.ksp.symbol.KSPropertySetter
@@ -94,7 +95,11 @@
origin.field.type
} else {
origin.field.asMemberOf(containingType)
- }
+ }.copyWithScope(
+ KSTypeVarianceResolverScope.PropertyGetterMethodReturnType(
+ getterMethod = origin as KspSyntheticPropertyMethodElement.Getter
+ )
+ )
}
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
index acef3af..94224fe 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
@@ -21,12 +21,11 @@
import androidx.room.compiler.processing.XExecutableParameterElement
import androidx.room.compiler.processing.XMemberContainer
import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.ksp.KSTypeVarianceResolverScope
import androidx.room.compiler.processing.ksp.KspAnnotated
-import androidx.room.compiler.processing.ksp.KspJvmTypeResolutionScope
import androidx.room.compiler.processing.ksp.KspMethodElement
import androidx.room.compiler.processing.ksp.KspProcessingEnv
import androidx.room.compiler.processing.ksp.KspType
-import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.KSTypeReference
@@ -60,15 +59,6 @@
override val hasDefaultValue: Boolean
get() = false
- private fun jvmTypeResolutionScope(container: KSDeclaration?): KspJvmTypeResolutionScope {
- return KspJvmTypeResolutionScope.MethodParameter(
- kspExecutableElement = enclosingElement,
- parameterIndex = 0, // Receiver param is the 1st one
- annotated = enclosingElement.declaration,
- container = container
- )
- }
-
override val type: KspType by lazy {
asMemberOf(enclosingElement.enclosingElement.type?.ksType)
}
@@ -102,8 +92,11 @@
return env.wrap(
originatingReference = receiverType,
ksType = asMemberReceiverType,
- ).withJvmTypeResolver(
- jvmTypeResolutionScope(
+ ).copyWithScope(
+ KSTypeVarianceResolverScope.MethodParameter(
+ kspExecutableElement = enclosingElement,
+ parameterIndex = 0, // Receiver param is the 1st one
+ annotated = enclosingElement.declaration,
container = ksType?.declaration
)
)
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
index 40d916e..f337713 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
@@ -60,19 +60,23 @@
runProcessorTest(sources = listOf(src), handler = handler)
}
- private fun XTestInvocation.assertFieldType(fieldName: String, expectedTypeName: String) {
+ private fun XTestInvocation.assertFieldType(
+ fieldName: String,
+ expectedJTypeName: String,
+ ) {
+ val expectedKTypeName = expectedJTypeName.replace("? extends", "out")
val sub = processingEnv.requireTypeElement("SubClass")
val subField = sub.getField(fieldName).asMemberOf(sub.type)
- assertThat(subField.asTypeName().java.toString()).isEqualTo(expectedTypeName)
+ assertThat(subField.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
if (isKsp) {
- assertThat(subField.asTypeName().kotlin.toString()).isEqualTo(expectedTypeName)
+ assertThat(subField.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
}
val base = processingEnv.requireTypeElement("BaseClass")
val baseField = base.getField(fieldName).asMemberOf(sub.type)
- assertThat(baseField.asTypeName().java.toString()).isEqualTo(expectedTypeName)
+ assertThat(baseField.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
if (isKsp) {
- assertThat(baseField.asTypeName().kotlin.toString()).isEqualTo(expectedTypeName)
+ assertThat(baseField.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
}
}
@@ -80,8 +84,8 @@
methodName: String,
paramName: String,
expectedJTypeName: String,
- expectedKTypeName: String,
) {
+ val expectedKTypeName = expectedJTypeName.replace("? extends", "out")
val sub = processingEnv.requireTypeElement("SubClass")
val subMethod = sub.getMethodByJvmName(methodName)
val paramIndex = subMethod.parameters.indexOf(subMethod.getParameter(paramName))
@@ -123,9 +127,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -145,9 +149,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -167,9 +171,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -189,9 +193,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -211,9 +215,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -233,9 +237,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -255,9 +259,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -277,9 +281,9 @@
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
@@ -298,24 +302,13 @@
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -331,24 +324,13 @@
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -362,38 +344,15 @@
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -409,24 +368,13 @@
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -440,38 +388,15 @@
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -487,24 +412,13 @@
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -518,38 +432,15 @@
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -563,38 +454,15 @@
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
+ invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<Baz>>")
- }
}
}
@@ -607,40 +475,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<Baz>>",
- "Foo<Bar<Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -653,35 +497,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -694,35 +519,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -735,41 +541,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -782,40 +563,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<Baz>>",
- "Foo<Bar<Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -828,46 +585,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<Baz>>",
- "Foo<Bar<Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -880,46 +607,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<Baz>>",
- "Foo<Bar<Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -932,17 +629,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertFieldType("varFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
+ invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -955,41 +651,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1002,38 +673,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertParamType("method", "param", "Foo<Bar<Baz>>", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method", "paramT1", "Foo<Bar<? extends Baz>>", "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1046,43 +695,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
-
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
-
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1095,53 +717,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1154,41 +739,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<Baz>>",
- "Foo<out Bar<Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varField", "Foo<? extends Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1201,53 +761,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<Bar<? extends Baz>>",
- "Foo<Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1260,41 +783,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
@@ -1307,41 +805,16 @@
) { invocation ->
invocation.assertFieldType("valField", "Foo<Bar<Baz>>")
invocation.assertFieldType("valFieldT1", "Foo<Bar<Baz>>")
- invocation.assertParamType(
- "method",
- "param",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT1",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
- invocation.assertParamType(
- "method",
- "paramT2",
- "Foo<? extends Bar<? extends Baz>>",
- "Foo<out Bar<out Baz>>"
- )
+ invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
+ invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "param", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT1", "Foo<? extends Bar<? extends Baz>>")
+ invocation.assertParamType("method", "paramT2", "Foo<? extends Bar<? extends Baz>>")
invocation.assertReturnType("methodReturn", "Foo<Bar<Baz>>")
invocation.assertReturnType("methodReturnT1", "Foo<Bar<Baz>>")
-
- // TODO(b/237280547): Make KSP type name match KAPT.
- if (invocation.isKsp) {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varField", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<Bar<Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<Bar<Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<Baz>>")
- } else {
- invocation.assertFieldType("valFieldT2", "Foo<Bar<? extends Baz>>")
- invocation.assertFieldType("varField", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT1", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertFieldType("varFieldT2", "Foo<? extends Bar<? extends Baz>>")
- invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
- }
+ invocation.assertReturnType("methodReturnT2", "Foo<Bar<? extends Baz>>")
}
}
}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
index f2c68e0..8f9a50a 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSAsMemberOfTest.kt
@@ -22,10 +22,12 @@
import androidx.room.compiler.processing.util.getField
import androidx.room.compiler.processing.util.getMethodByJvmName
import androidx.room.compiler.processing.util.runKspTest
+import androidx.room.compiler.processing.util.runProcessorTest
import com.google.common.truth.Truth.assertThat
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeName
+import com.squareup.javapoet.WildcardTypeName
import org.junit.Test
class KSAsMemberOfTest {
@@ -46,7 +48,7 @@
""".trimIndent()
)
- runKspTest(sources = listOf(src)) { invocation ->
+ runProcessorTest(sources = listOf(src)) { invocation ->
val base = invocation.processingEnv.requireTypeElement("BaseClass")
val sub = invocation.processingEnv.requireType("SubClass")
base.getField("normalInt").let { prop ->
@@ -77,7 +79,7 @@
val listOfStringsTypeName =
ParameterizedTypeName.get(
List::class.className(),
- String::class.className()
+ WildcardTypeName.subtypeOf(String::class.className())
)
base.getField("mapOfStringToGeneric2").let { prop ->
assertThat(
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
index a2131bd..2bd5ed4 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
@@ -156,6 +156,10 @@
package $pkg
class MyType
class MyGeneric<T>
+ class MyGenericIn<in T>
+ class MyGenericOut<out T>
+ class MyGenericMultipleParameters<T1: MyGeneric<*>, T2: MyGeneric<T1>>
+ typealias MyLambdaTypeAlias = (@JvmWildcard MyType) -> @JvmWildcard MyType
enum class MyEnum {
VAL1,
VAL2;
@@ -221,6 +225,58 @@
fun method11(iter: Iterable<String>): Iterable<String> = TODO()
fun method12(iter: Iterable<Number>): Iterable<Number> = TODO()
fun method13(iter: Iterable<MyType>): Iterable<MyType> = TODO()
+ fun method14(list: List<MyLambdaTypeAlias>): MyLambdaTypeAlias = TODO()
+ fun method15(
+ list: List<MyGenericMultipleParameters<*, *>>
+ ): List<MyGenericMultipleParameters<*, *>> = TODO()
+ fun method16(
+ param: MyGenericIn<MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGenericIn<MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method17(
+ param: MyGeneric<MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGeneric<MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method18(
+ param: MyGeneric<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGeneric<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method19(
+ param: MyGeneric<out MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGeneric<out MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method20(
+ param: MyGeneric<MyGeneric<out MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGeneric<MyGeneric<out MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method21(
+ param: MyGeneric<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGeneric<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method22(
+ param: MyGenericIn<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGenericIn<in MyGeneric<MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method23(
+ param: MyGenericIn<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>>
+ ): MyGenericIn<MyGeneric<in MyGenericIn<MyGeneric<MyType>>>> = TODO()
+ fun method24(
+ param: MyGenericOut<MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGenericOut<MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method25(
+ param: MyGeneric<MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGeneric<MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method26(
+ param: MyGeneric<in MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGeneric<in MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method27(
+ param: MyGeneric<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGeneric<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method28(
+ param: MyGeneric<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGeneric<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method29(
+ param: MyGeneric<MyGeneric<in MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGeneric<MyGeneric<in MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method30(
+ param: MyGenericOut<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGenericOut<out MyGeneric<MyGenericOut<MyGeneric<MyType>>>> = TODO()
+ fun method31(
+ param: MyGenericOut<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>>
+ ): MyGenericOut<MyGeneric<out MyGenericOut<MyGeneric<MyType>>>> = TODO()
}
""".trimIndent()
), listOf("Subject")
@@ -284,7 +340,7 @@
sealedListParent: List<GrandParentSealed.Parent1>,
sealedListChild: List<GrandParentSealed.Parent2.Child1>,
jvmWildcard: List<@JvmWildcard String>,
- suppressJvmWildcard: List<@JvmSuppressWildcards Number>
+ suppressJvmWildcard: List<@JvmSuppressWildcards Number>,
) {
var propWithFinalType: String = ""
var propWithOpenType: Number = 3
@@ -305,14 +361,18 @@
fun listSealedListGrandParent(list: List<GrandParentSealed>): List<GrandParentSealed> { TODO() }
fun listSealedListParent(list: List<GrandParentSealed.Parent1>): List<GrandParentSealed.Parent1> { TODO() }
fun listSealedListChild(list: List<GrandParentSealed.Parent2.Child1>): List<GrandParentSealed.Parent2.Child1> { TODO() }
+ fun explicitOutOnInvariant_onType1(
+ list: MyGeneric<out MyGeneric<MyType>>
+ ): MyGeneric<out MyGeneric<MyType>> { TODO() }
+ fun explicitOutOnInvariant_onType2(
+ list: MyGeneric<MyGeneric<out MyType>>
+ ): MyGeneric<MyGeneric<out MyType>> { TODO() }
fun explicitJvmWildcard(
list: List<@JvmWildcard String>
): List<@JvmWildcard String> { TODO() }
-
fun explicitJvmSuppressWildcard_OnType(
list: List<@JvmSuppressWildcards Number>
): List<@JvmSuppressWildcards Number> { TODO() }
-
fun explicitJvmSuppressWildcard_OnType2(
list: @JvmSuppressWildcards List<Number>
): @JvmSuppressWildcards List<Number> { TODO() }
@@ -327,11 +387,9 @@
fun suspendExplicitJvmWildcard(
list: List<@JvmWildcard String>
): List<@JvmWildcard String> { TODO() }
-
fun suspendExplicitJvmSuppressWildcard_OnType(
list: List<@JvmSuppressWildcards Number>
): List<@JvmSuppressWildcards Number> { TODO() }
-
fun suspendExplicitJvmSuppressWildcard_OnType2(
list: @JvmSuppressWildcards List<Number>
): @JvmSuppressWildcards List<Number> { TODO() }
diff --git a/room/room-migration/api/restricted_current.ignore b/room/room-migration/api/restricted_current.ignore
new file mode 100644
index 0000000..1e1b7dd
--- /dev/null
+++ b/room/room-migration/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+InvalidNullConversion: androidx.room.migration.bundle.SchemaEquality#isSchemaEqual(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter other in androidx.room.migration.bundle.SchemaEquality.isSchemaEqual(T other)
diff --git a/room/room-migration/api/restricted_current.txt b/room/room-migration/api/restricted_current.txt
index 8c3e714..1c948b9 100644
--- a/room/room-migration/api/restricted_current.txt
+++ b/room/room-migration/api/restricted_current.txt
@@ -187,7 +187,7 @@
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SchemaEquality<T> {
- method public boolean isSchemaEqual(T? other);
+ method public boolean isSchemaEqual(T other);
}
}
diff --git a/room/room-runtime/api/current.txt b/room/room-runtime/api/current.txt
index 883d5f0..316622e 100644
--- a/room/room-runtime/api/current.txt
+++ b/room/room-runtime/api/current.txt
@@ -69,7 +69,7 @@
method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
method public void runInTransaction(Runnable body);
- method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
+ method public <V> V runInTransaction(java.util.concurrent.Callable<V> body);
method @Deprecated public void setTransactionSuccessful();
property public androidx.room.InvalidationTracker invalidationTracker;
property public boolean isOpen;
diff --git a/room/room-runtime/api/public_plus_experimental_current.txt b/room/room-runtime/api/public_plus_experimental_current.txt
index 5a5ebdf..5c47de6 100644
--- a/room/room-runtime/api/public_plus_experimental_current.txt
+++ b/room/room-runtime/api/public_plus_experimental_current.txt
@@ -77,7 +77,7 @@
method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
method public void runInTransaction(Runnable body);
- method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
+ method public <V> V runInTransaction(java.util.concurrent.Callable<V> body);
method @Deprecated public void setTransactionSuccessful();
property public androidx.room.InvalidationTracker invalidationTracker;
property public boolean isOpen;
diff --git a/room/room-runtime/api/restricted_current.ignore b/room/room-runtime/api/restricted_current.ignore
index bb7df6a..9a2cd17 100644
--- a/room/room-runtime/api/restricted_current.ignore
+++ b/room/room-runtime/api/restricted_current.ignore
@@ -1,6 +1,20 @@
// Baseline format: 1.0
+InvalidNullConversion: androidx.room.EntityDeletionOrUpdateAdapter#bind(androidx.sqlite.db.SupportSQLiteStatement, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityDeletionOrUpdateAdapter.bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity)
+InvalidNullConversion: androidx.room.EntityDeletionOrUpdateAdapter#handle(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityDeletionOrUpdateAdapter.handle(T entity)
InvalidNullConversion: androidx.room.EntityInsertionAdapter#bind(androidx.sqlite.db.SupportSQLiteStatement, T) parameter #0:
Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter statement in androidx.room.EntityInsertionAdapter.bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity)
+InvalidNullConversion: androidx.room.EntityInsertionAdapter#bind(androidx.sqlite.db.SupportSQLiteStatement, T) parameter #1:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityInsertionAdapter.bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity)
+InvalidNullConversion: androidx.room.EntityInsertionAdapter#insert(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityInsertionAdapter.insert(T entity)
+InvalidNullConversion: androidx.room.EntityInsertionAdapter#insertAndReturnId(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityInsertionAdapter.insertAndReturnId(T entity)
+InvalidNullConversion: androidx.room.EntityUpsertionAdapter#upsert(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityUpsertionAdapter.upsert(T entity)
+InvalidNullConversion: androidx.room.EntityUpsertionAdapter#upsertAndReturnId(T) parameter #0:
+ Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter entity in androidx.room.EntityUpsertionAdapter.upsertAndReturnId(T entity)
ParameterNameChange: androidx.room.RoomDatabase.JournalMode#valueOf(String) parameter #0:
diff --git a/room/room-runtime/api/restricted_current.txt b/room/room-runtime/api/restricted_current.txt
index 760ce8c..db80a4c 100644
--- a/room/room-runtime/api/restricted_current.txt
+++ b/room/room-runtime/api/restricted_current.txt
@@ -35,19 +35,19 @@
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityDeletionOrUpdateAdapter<T> extends androidx.room.SharedSQLiteStatement {
ctor public EntityDeletionOrUpdateAdapter(androidx.room.RoomDatabase database);
- method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T? entity);
- method public final int handle(T? entity);
+ method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity);
+ method public final int handle(T entity);
method public final int handleMultiple(Iterable<? extends T> entities);
method public final int handleMultiple(T![] entities);
}
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class EntityInsertionAdapter<T> extends androidx.room.SharedSQLiteStatement {
ctor public EntityInsertionAdapter(androidx.room.RoomDatabase database);
- method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T? entity);
- method public final void insert(T? entity);
+ method protected abstract void bind(androidx.sqlite.db.SupportSQLiteStatement statement, T entity);
+ method public final void insert(T entity);
method public final void insert(T![] entities);
method public final void insert(Iterable<? extends T> entities);
- method public final long insertAndReturnId(T? entity);
+ method public final long insertAndReturnId(T entity);
method public final long[] insertAndReturnIdsArray(java.util.Collection<? extends T> entities);
method public final long[] insertAndReturnIdsArray(T![] entities);
method public final Long![] insertAndReturnIdsArrayBox(java.util.Collection<? extends T> entities);
@@ -58,10 +58,10 @@
@RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class EntityUpsertionAdapter<T> {
ctor public EntityUpsertionAdapter(androidx.room.EntityInsertionAdapter<T> insertionAdapter, androidx.room.EntityDeletionOrUpdateAdapter<T> updateAdapter);
- method public void upsert(T? entity);
+ method public void upsert(T entity);
method public void upsert(T![] entities);
method public void upsert(Iterable<? extends T> entities);
- method public long upsertAndReturnId(T? entity);
+ method public long upsertAndReturnId(T entity);
method public long[] upsertAndReturnIdsArray(T![] entities);
method public long[] upsertAndReturnIdsArray(java.util.Collection<? extends T> entities);
method public Long![] upsertAndReturnIdsArrayBox(T![] entities);
@@ -122,7 +122,7 @@
method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query, optional android.os.CancellationSignal? signal);
method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery query);
method public void runInTransaction(Runnable body);
- method public <V> V! runInTransaction(java.util.concurrent.Callable<V> body);
+ method public <V> V runInTransaction(java.util.concurrent.Callable<V> body);
method @Deprecated public void setTransactionSuccessful();
property public androidx.room.InvalidationTracker invalidationTracker;
property public boolean isOpen;
@@ -305,7 +305,7 @@
method public static android.database.Cursor copyAndClose(android.database.Cursor c);
method public static int getColumnIndex(android.database.Cursor c, String name);
method public static int getColumnIndexOrThrow(android.database.Cursor c, String name);
- method public static inline <R> R! useCursor(android.database.Cursor, kotlin.jvm.functions.Function1<? super android.database.Cursor,? extends R> block);
+ method public static inline <R> R useCursor(android.database.Cursor, kotlin.jvm.functions.Function1<? super android.database.Cursor,? extends R> block);
method public static android.database.Cursor wrapMappedColumns(android.database.Cursor cursor, String![] columnNames, int[] mapping);
}
diff --git a/settings.gradle b/settings.gradle
index f69f595..1a50a33 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,6 +2,9 @@
import androidx.build.gradle.gcpbuildcache.GcpBuildCache
import androidx.build.gradle.gcpbuildcache.GcpBuildCacheServiceFactory
+import java.util.regex.Matcher
+import java.util.regex.Pattern
+
pluginManagement {
repositories {
maven {
@@ -303,6 +306,22 @@
includeProject(name, null, filter)
}
+// A map of project path to a set of project paths referenced directly by this project.
+@Field Map<String, Set<String>> projectReferences = new HashMap<String, Set<String>>()
+
+// A map of all project paths to their project directory.
+@Field Map<String, File> allProjects = new HashMap<String, File>()
+// A set of projects that the user asked to filter to.
+@Field Set<String> filteredProjects = new HashSet<String>()
+
+@Field Pattern projectReferencePattern = Pattern.compile(
+ "(project|projectOrArtifact)\\((path: )?[\"'](?<name>\\S*)[\"'](, configuration: .*)?\\)"
+)
+@Field Pattern inspection = Pattern.compile("packageInspector\\(project, \"(.*)\"\\)")
+@Field Pattern composePlugin = Pattern.compile("id\\(\"AndroidXComposePlugin\"\\)")
+@Field Pattern paparazziPlugin = Pattern.compile("id\\(\"AndroidXPaparazziPlugin\"\\)")
+@Field Pattern iconGenerator = Pattern.compile("IconGenerationTask\\.register")
+
// Calling includeProject(name, filePath) is shorthand for:
//
// include(name)
@@ -313,9 +332,7 @@
// the Maven artifactId
//
def includeProject(name, filePath, List<BuildType> filter = []) {
- if (!shouldIncludeForFilter(filter)) return
- settings.include(name)
-
+ if (shouldIncludeForFilter(filter)) filteredProjects.add(name)
def file
if (filePath != null) {
if (filePath instanceof String) {
@@ -326,9 +343,35 @@
} else {
file = filePath
}
- project(name).projectDir = file
} else {
- file = project(name).projectDir
+ file = new File(rootDir, name.substring(1).replace(":", "/"))
+ }
+ allProjects[name] = file
+ File buildGradle = new File(file, "build.gradle")
+ if (buildGradle.exists()) {
+ Set<String> links = new HashSet<String>()
+ for (line in buildGradle.readLines()) {
+ Matcher m = projectReferencePattern.matcher(line)
+ if (m.find()) {
+ links.add(m.group("name"))
+ }
+ Matcher matcherInspection = inspection.matcher(line)
+ if (matcherInspection) {
+ links.add(matcherInspection.group(1))
+ }
+ if (composePlugin.matcher(line).find()) {
+ links.add(":compose:compiler:compiler")
+ links.add(":compose:lint:internal-lint-checks")
+ }
+ if (paparazziPlugin.matcher(line).find()) {
+ links.add(":test:screenshot:screenshot-proto")
+ links.add(":internal-testutils-paparazzi")
+ }
+ if (iconGenerator.matcher(line).find()) {
+ links.add(":compose:material:material:icons:generator")
+ }
+ }
+ projectReferences[name] = links
}
if (!file.exists()) {
// This option is supported so that development/simplify_build_failure.sh can try
@@ -426,7 +469,6 @@
includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-dep", [BuildType.MAIN])
includeProject(":buildSrc-tests:max-dep-versions:buildSrc-tests-max-dep-versions-main", [BuildType.MAIN])
}
-includeProject(":buildSrc-tests:project-subsets", [BuildType.MAIN])
includeProject(":camera:camera-camera2", [BuildType.CAMERA])
includeProject(":camera:camera-camera2-pipe", [BuildType.CAMERA])
includeProject(":camera:camera-camera2-pipe-integration", [BuildType.CAMERA])
@@ -567,7 +609,7 @@
includeProject(":compose:ui:ui-graphics", [BuildType.COMPOSE])
includeProject(":compose:ui:ui-graphics-lint", [BuildType.COMPOSE])
includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark", "compose/ui/ui-graphics/benchmark", [BuildType.COMPOSE])
-includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark:test", [BuildType.COMPOSE])
+includeProject(":compose:ui:ui-graphics:ui-graphics-benchmark:test", "compose/ui/ui-graphics/benchmark/test", [BuildType.COMPOSE])
includeProject(":compose:ui:ui-graphics:ui-graphics-samples", "compose/ui/ui-graphics/samples", [BuildType.COMPOSE])
includeProject(":compose:ui:ui-inspection", [BuildType.COMPOSE])
includeProject(":compose:ui:ui-lint", [BuildType.COMPOSE])
@@ -680,6 +722,7 @@
includeProject(":glance:glance-appwidget", [BuildType.GLANCE])
includeProject(":glance:glance-appwidget-preview", [BuildType.GLANCE])
includeProject(":glance:glance-appwidget-proto", [BuildType.GLANCE])
+includeProject(":glance:glance-appwidget:glance-appwidget-samples", "glance/glance-appwidget/samples", [BuildType.GLANCE])
includeProject(":glance:glance-appwidget:integration-tests:demos", [BuildType.GLANCE])
includeProject(":glance:glance-appwidget:integration-tests:macrobenchmark", [BuildType.GLANCE])
includeProject(":glance:glance-appwidget:integration-tests:macrobenchmark-target", [BuildType.GLANCE])
@@ -1127,3 +1170,20 @@
// Workaround for b/203825166
includeBuild("placeholder")
+
+// For a given project path add the transitive project references to the include set.
+void addReferences(String projectPath, Set<String> included) {
+ if (projectPath in included) return
+ included.add(projectPath)
+ for (reference in projectReferences[projectPath]) {
+ addReferences(reference, included)
+ }
+}
+Set<String> projectsToInclude = new HashSet<>()
+for (filteredProject in filteredProjects) {
+ addReferences(filteredProject, projectsToInclude)
+}
+for (entry in projectsToInclude) {
+ settings.include(entry)
+ project(entry).projectDir = allProjects[entry]
+}
diff --git a/sqlite/sqlite-ktx/api/current.txt b/sqlite/sqlite-ktx/api/current.txt
index 26086b4..3b12c09 100644
--- a/sqlite/sqlite-ktx/api/current.txt
+++ b/sqlite/sqlite-ktx/api/current.txt
@@ -2,7 +2,7 @@
package androidx.sqlite.db {
public final class SupportSQLiteDatabaseKt {
- method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+ method public static inline <T> T transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
}
}
diff --git a/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt b/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt
index 26086b4..3b12c09 100644
--- a/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt
+++ b/sqlite/sqlite-ktx/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
package androidx.sqlite.db {
public final class SupportSQLiteDatabaseKt {
- method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+ method public static inline <T> T transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
}
}
diff --git a/sqlite/sqlite-ktx/api/restricted_current.txt b/sqlite/sqlite-ktx/api/restricted_current.txt
index 26086b4..3b12c09 100644
--- a/sqlite/sqlite-ktx/api/restricted_current.txt
+++ b/sqlite/sqlite-ktx/api/restricted_current.txt
@@ -2,7 +2,7 @@
package androidx.sqlite.db {
public final class SupportSQLiteDatabaseKt {
- method public static inline <T> T! transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
+ method public static inline <T> T transaction(androidx.sqlite.db.SupportSQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super androidx.sqlite.db.SupportSQLiteDatabase,? extends T> body);
}
}
diff --git a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt
index 846f838..9d1ac4b 100644
--- a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/ComparableSubject.kt
@@ -37,4 +37,17 @@
fail("Expected to be less than $other, but was $actual")
}
}
+
+ /**
+ * Checks that the subject is greater than or equal to [other].
+ *
+ * @throws NullPointerException if [actual] or [other] is `null`.
+ */
+ fun isAtLeast(other: T?) {
+ requireNonNull(actual) { "Expected to be at least $other, but was $actual" }
+ requireNonNull(other) { "Expected to be at least $other, but was $actual" }
+ if (actual < other) {
+ fail("Expected to be at least $other, but was $actual")
+ }
+ }
}
\ No newline at end of file
diff --git a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt
index b37c5d5..548e729 100644
--- a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt
+++ b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/ComparableSubjectTest.kt
@@ -35,6 +35,9 @@
assertFailsWith<NullPointerException> {
assertThat(6).isLessThan(null)
}
+ assertFailsWith<NullPointerException> {
+ assertThat(6).isAtLeast(null)
+ }
}
@Test
@@ -52,16 +55,31 @@
}
}
+ @Test
+ fun isAtLeast() {
+ assertThat(4).isAtLeast(3)
+ assertThat(4).isAtLeast(4)
+ assertFailsWith<AssertionError> {
+ assertThat(4).isAtLeast(5)
+ }
+ }
+
// Brief tests with other comparable types (no negative test cases)
@Test
fun longs() {
assertThat(4L).isLessThan(5L)
+
+ assertThat(4L).isAtLeast(4L)
+ assertThat(4L).isAtLeast(3L)
}
@Test
fun strings() {
assertThat("gak").isLessThan("kak")
+
+ assertThat("kak").isAtLeast("kak")
+ assertThat("kak").isAtLeast("gak")
}
@Test
diff --git a/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt b/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt
index aecc829..dc0d267 100644
--- a/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt
+++ b/testutils/testutils-paging/src/main/java/androidx/paging/TestPagingDataDiffer.kt
@@ -16,11 +16,11 @@
package androidx.paging
-import kotlinx.coroutines.CoroutineDispatcher
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.Dispatchers
-class TestPagingDataDiffer<T : Any>(mainDispatcher: CoroutineDispatcher = Dispatchers.Main) :
- PagingDataDiffer<T>(noopDifferCallback, mainDispatcher) {
+class TestPagingDataDiffer<T : Any>(mainContext: CoroutineContext = Dispatchers.Main) :
+ PagingDataDiffer<T>(noopDifferCallback, mainContext) {
val currentList: List<T> get() = List(size) { i -> get(i)!! }
diff --git a/tracing/tracing-ktx/api/1.2.0-beta04.txt b/tracing/tracing-ktx/api/1.2.0-beta04.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/1.2.0-beta04.txt
+++ b/tracing/tracing-ktx/api/1.2.0-beta04.txt
@@ -2,10 +2,10 @@
package androidx.tracing {
public final class TraceKt {
- method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
- method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
}
}
diff --git a/tracing/tracing-ktx/api/current.txt b/tracing/tracing-ktx/api/current.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/current.txt
+++ b/tracing/tracing-ktx/api/current.txt
@@ -2,10 +2,10 @@
package androidx.tracing {
public final class TraceKt {
- method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
- method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
}
}
diff --git a/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt b/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt
+++ b/tracing/tracing-ktx/api/public_plus_experimental_1.2.0-beta04.txt
@@ -2,10 +2,10 @@
package androidx.tracing {
public final class TraceKt {
- method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
- method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
}
}
diff --git a/tracing/tracing-ktx/api/public_plus_experimental_current.txt b/tracing/tracing-ktx/api/public_plus_experimental_current.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/public_plus_experimental_current.txt
+++ b/tracing/tracing-ktx/api/public_plus_experimental_current.txt
@@ -2,10 +2,10 @@
package androidx.tracing {
public final class TraceKt {
- method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
- method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
}
}
diff --git a/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt b/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt
+++ b/tracing/tracing-ktx/api/restricted_1.2.0-beta04.txt
@@ -2,10 +2,10 @@
package androidx.tracing {
public final class TraceKt {
- method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
- method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
}
}
diff --git a/tracing/tracing-ktx/api/restricted_current.txt b/tracing/tracing-ktx/api/restricted_current.txt
index 13d99d1..c866186 100644
--- a/tracing/tracing-ktx/api/restricted_current.txt
+++ b/tracing/tracing-ktx/api/restricted_current.txt
@@ -2,10 +2,10 @@
package androidx.tracing {
public final class TraceKt {
- method public static inline <T> T! trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
- method public static inline <T> T! trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(String label, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T trace(kotlin.jvm.functions.Function0<java.lang.String> lazyLabel, kotlin.jvm.functions.Function0<? extends T> block);
method public static suspend inline <T> Object? traceAsync(String methodName, int cookie, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
- method public static inline <T> T! traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
+ method public static inline <T> T traceAsync(kotlin.jvm.functions.Function0<java.lang.String> lazyMethodName, kotlin.jvm.functions.Function0<java.lang.Integer> lazyCookie, kotlin.jvm.functions.Function0<? extends T> block);
}
}
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt
index 29b1866..7ecfec8 100644
--- a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt
@@ -18,10 +18,16 @@
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.tv.foundation.ExperimentalTvFoundationApi
+import androidx.tv.foundation.PivotOffsets
import androidx.tv.foundation.lazy.list.TvLazyColumn
import androidx.tv.foundation.lazy.list.TvLazyRow
@@ -30,19 +36,29 @@
@Composable
fun LazyRowsAndColumns() {
- TvLazyColumn(verticalArrangement = Arrangement.spacedBy(20.dp)) {
- items(rowsCount) { SampleLazyRow() }
+ var pivotOffset by remember { mutableStateOf(PivotOffsets()) }
+ TvLazyColumn(
+ pivotOffsets = pivotOffset,
+ verticalArrangement = Arrangement.spacedBy(20.dp)
+ ) {
+ items(rowsCount) { rowIndex ->
+ SampleLazyRow(Modifier.onFocusChanged {
+ if (it.hasFocus) {
+ pivotOffset = if (rowIndex == 2) PivotOffsets(0f) else PivotOffsets()
+ }
+ })
+ }
}
}
@OptIn(ExperimentalTvFoundationApi::class)
@Composable
-fun SampleLazyRow() {
+fun SampleLazyRow(modifier: Modifier = Modifier) {
val colors = listOf(Color.Red, Color.Magenta, Color.Green, Color.Yellow, Color.Blue, Color.Cyan)
val backgroundColors = List(columnsCount) { colors.random() }
FocusGroup {
- TvLazyRow(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
+ TvLazyRow(modifier, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
backgroundColors.forEachIndexed { index, backgroundColor ->
item {
Card(
diff --git a/tv/tv-foundation/api/api_lint.ignore b/tv/tv-foundation/api/api_lint.ignore
new file mode 100644
index 0000000..599cbcc
--- /dev/null
+++ b/tv/tv-foundation/api/api_lint.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.tv.foundation.lazy.grid.TvLazyGridState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.tv.foundation.lazy.grid.TvLazyGridState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.tv.foundation.lazy.list.TvLazyListState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.tv.foundation.lazy.list.TvLazyListState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field TvLazyGridLayoutInfo.reverseLayout:
+ Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field TvLazyListLayoutInfo.reverseLayout:
+ Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
index cec085f..51f87fd 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListTest.kt
@@ -84,7 +84,6 @@
import java.util.concurrent.CountDownLatch
import kotlin.math.roundToInt
import kotlinx.coroutines.runBlocking
-import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -813,7 +812,6 @@
}
}
- @Ignore // b/268211857
@Test
fun scroll_makeListSmaller_scroll() {
var items by mutableStateOf((1..100).toList())
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
index 9d7df7f..635441e 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/ScrollableWithPivot.kt
@@ -79,7 +79,7 @@
factory = {
val coroutineScope = rememberCoroutineScope()
val keepFocusedChildInViewModifier =
- remember(coroutineScope, orientation, state, reverseDirection) {
+ remember(coroutineScope, orientation, state, reverseDirection, pivotOffsets) {
ContentInViewModifier(
coroutineScope, orientation, state, reverseDirection, pivotOffsets)
}
diff --git a/tv/tv-material/api/public_plus_experimental_current.txt b/tv/tv-material/api/public_plus_experimental_current.txt
index 3f5fc27..bebfaef 100644
--- a/tv/tv-material/api/public_plus_experimental_current.txt
+++ b/tv/tv-material/api/public_plus_experimental_current.txt
@@ -18,12 +18,6 @@
property public final androidx.tv.material3.Border None;
}
- @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class BorderIndication implements androidx.compose.foundation.Indication {
- ctor public BorderIndication(androidx.compose.ui.graphics.Brush brush, float width, androidx.compose.ui.graphics.Shape shape, optional float inset);
- ctor public BorderIndication(androidx.tv.material3.Border border);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- }
-
@androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ButtonBorder {
}
@@ -147,6 +141,19 @@
property public final int activeItemIndex;
}
+ @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class CheckboxColors {
+ }
+
+ @androidx.tv.material3.ExperimentalTvMaterial3Api public final class CheckboxDefaults {
+ method @androidx.compose.runtime.Composable public androidx.tv.material3.CheckboxColors colors(optional long checkedColor, optional long uncheckedColor, optional long checkmarkColor, optional long disabledCheckedColor, optional long disabledUncheckedColor, optional long disabledIndeterminateColor);
+ field public static final androidx.tv.material3.CheckboxDefaults INSTANCE;
+ }
+
+ public final class CheckboxKt {
+ method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.tv.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+ method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.tv.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+ }
+
@androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ClickableSurfaceBorder {
}
@@ -292,11 +299,6 @@
property public final androidx.tv.material3.Glow None;
}
- @androidx.compose.runtime.Stable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class GlowIndication implements androidx.compose.foundation.Indication {
- ctor public GlowIndication(long color, androidx.compose.ui.graphics.Shape shape, float glowBlurRadius, float offsetX, float offsetY);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- }
-
@androidx.tv.material3.ExperimentalTvMaterial3Api public final class IconButtonDefaults {
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ButtonBorder border(optional androidx.tv.material3.Border border, optional androidx.tv.material3.Border focusedBorder, optional androidx.tv.material3.Border pressedBorder, optional androidx.tv.material3.Border disabledBorder, optional androidx.tv.material3.Border focusedDisabledBorder);
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ButtonColors colors(optional long containerColor, optional long contentColor, optional long focusedContainerColor, optional long focusedContentColor, optional long pressedContainerColor, optional long pressedContentColor, optional long disabledContainerColor, optional long disabledContentColor);
@@ -350,10 +352,6 @@
method public androidx.compose.ui.Modifier immersiveListItem(androidx.compose.ui.Modifier, int index);
}
- public final class IndicationsKt {
- method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static androidx.tv.material3.GlowIndication rememberGlowIndication(optional long color, optional androidx.compose.ui.graphics.Shape shape, optional float glowBlurRadius, optional float offsetX, optional float offsetY);
- }
-
public final class MaterialTheme {
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ColorScheme getColorScheme();
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.Shapes getShapes();
@@ -412,11 +410,6 @@
field public static final androidx.tv.material3.OutlinedIconButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ScaleIndication implements androidx.compose.foundation.Indication {
- ctor public ScaleIndication(float scale);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- }
-
@androidx.tv.material3.ExperimentalTvMaterial3Api public sealed interface ScrollPauseHandle {
method public void resumeAutoScroll();
}
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxScreenshotTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxScreenshotTest.kt
new file mode 100644
index 0000000..0b5378e
--- /dev/null
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxScreenshotTest.kt
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.tv.material3
+
+import android.os.Build
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.platform.LocalInputModeManager
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.state.ToggleableState
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.isToggleable
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performKeyInput
+import androidx.compose.ui.test.performMouseInput
+import androidx.compose.ui.test.pressKey
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@MediumTest
+@RunWith(Parameterized::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+@OptIn(ExperimentalTestApi::class, ExperimentalTvMaterial3Api::class)
+class CheckboxScreenshotTest(private val scheme: ColorSchemeWrapper) {
+
+ @get:Rule
+ val rule = createComposeRule()
+
+ @get:Rule
+ val screenshotRule = AndroidXScreenshotTestRule(TV_GOLDEN_MATERIAL3)
+
+ val wrap = Modifier.wrapContentSize(Alignment.TopStart)
+
+ private val wrapperTestTag = "checkboxWrapper"
+
+ @Test
+ fun checkBox_checked() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(checked = true, onCheckedChange = { })
+ }
+ }
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_checked")
+ }
+
+ @Test
+ fun checkBox_unchecked() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(modifier = wrap, checked = false, onCheckedChange = { })
+ }
+ }
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_unchecked")
+ }
+
+ @Test
+ fun checkBox_pressed() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(modifier = wrap, checked = false, onCheckedChange = { })
+ }
+ }
+
+ rule.mainClock.autoAdvance = false
+ rule.onNode(isToggleable())
+ .performKeyInput { pressKey(Key.DirectionCenter) }
+
+ rule.mainClock.advanceTimeByFrame()
+ rule.waitForIdle() // Wait for measure
+ rule.mainClock.advanceTimeBy(milliseconds = 200)
+
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_pressed")
+ }
+
+ @Test
+ fun checkBox_indeterminate() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ TriStateCheckbox(
+ state = ToggleableState.Indeterminate,
+ modifier = wrap,
+ onClick = {}
+ )
+ }
+ }
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_indeterminate")
+ }
+
+ @Test
+ fun checkBox_disabled_checked() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(
+ modifier = wrap,
+ checked = true,
+ enabled = false,
+ onCheckedChange = { })
+ }
+ }
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_disabled_checked")
+ }
+
+ @Test
+ fun checkBox_disabled_unchecked() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(
+ modifier = wrap,
+ checked = false,
+ enabled = false,
+ onCheckedChange = { })
+ }
+ }
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_disabled_unchecked")
+ }
+
+ @Test
+ fun checkBox_disabled_indeterminate() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ TriStateCheckbox(
+ state = ToggleableState.Indeterminate,
+ enabled = false,
+ modifier = wrap,
+ onClick = {}
+ )
+ }
+ }
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_disabled_indeterminate")
+ }
+
+ @Test
+ fun checkBox_unchecked_animateToChecked() {
+ val isChecked = mutableStateOf(false)
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(
+ modifier = wrap,
+ checked = isChecked.value,
+ onCheckedChange = { isChecked.value = it }
+ )
+ }
+ }
+
+ rule.mainClock.autoAdvance = false
+
+ rule.runOnIdle {
+ isChecked.value = true
+ }
+
+ rule.mainClock.advanceTimeByFrame()
+ rule.waitForIdle() // Wait for measure
+ rule.mainClock.advanceTimeBy(milliseconds = 80)
+
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_unchecked_animateToChecked")
+ }
+
+ @Test
+ fun checkBox_checked_animateToUnchecked() {
+ val isChecked = mutableStateOf(true)
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(
+ modifier = wrap,
+ checked = isChecked.value,
+ onCheckedChange = { isChecked.value = it }
+ )
+ }
+ }
+
+ rule.mainClock.autoAdvance = false
+
+ rule.runOnIdle {
+ isChecked.value = false
+ }
+
+ rule.mainClock.advanceTimeByFrame()
+ rule.waitForIdle() // Wait for measure
+ rule.mainClock.advanceTimeBy(milliseconds = 80)
+
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_checked_animateToUnchecked")
+ }
+
+ @Test
+ fun checkBox_hover() {
+ rule.setMaterialContent(scheme.colorScheme) {
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(
+ modifier = wrap,
+ checked = true,
+ onCheckedChange = { }
+ )
+ }
+ }
+
+ rule.onNode(isToggleable())
+ .performMouseInput { enter(center) }
+
+ rule.waitForIdle()
+
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_hover")
+ }
+
+ @Test
+ fun checkBox_focus() {
+ val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
+
+ rule.setMaterialContent(scheme.colorScheme) {
+ localInputModeManager = LocalInputModeManager.current
+ Box(wrap.testTag(wrapperTestTag)) {
+ Checkbox(
+ modifier = wrap
+ .focusRequester(focusRequester),
+ checked = true,
+ onCheckedChange = { }
+ )
+ }
+ }
+
+ rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
+ focusRequester.requestFocus()
+ }
+
+ rule.waitForIdle()
+
+ assertToggeableAgainstGolden("checkBox_${scheme.name}_focus")
+ }
+
+ private fun assertToggeableAgainstGolden(goldenName: String) {
+ // TODO: replace with find(isToggeable()) after b/157687898 is fixed
+ rule.onNodeWithTag(wrapperTestTag)
+ .captureToImage()
+ .assertAgainstGolden(screenshotRule, goldenName)
+ }
+
+ // Provide the ColorScheme and their name parameter in a ColorSchemeWrapper.
+ // This makes sure that the default method name and the initial Scuba image generated
+ // name is as expected.
+ companion object {
+ @OptIn(ExperimentalTvMaterial3Api::class)
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun parameters() = arrayOf(
+ ColorSchemeWrapper("lightTheme", lightColorScheme()),
+ ColorSchemeWrapper("darkTheme", darkColorScheme()),
+ )
+ }
+
+ @OptIn(ExperimentalTvMaterial3Api::class)
+ class ColorSchemeWrapper constructor(val name: String, val colorScheme: ColorScheme) {
+ override fun toString(): String {
+ return name
+ }
+ }
+}
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxTest.kt
new file mode 100644
index 0000000..d83784a
--- /dev/null
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/CheckboxTest.kt
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.tv.material3
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.semantics.focused
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.SemanticsMatcher
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertHasClickAction
+import androidx.compose.ui.test.assertHasNoClickAction
+import androidx.compose.ui.test.assertIsEnabled
+import androidx.compose.ui.test.assertIsOff
+import androidx.compose.ui.test.assertIsOn
+import androidx.compose.ui.test.isFocusable
+import androidx.compose.ui.test.isNotFocusable
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performClick
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalTvMaterial3Api::class)
+class CheckboxTest {
+
+ @get:Rule
+ val rule = createComposeRule()
+
+ private val defaultTag = "checkbox"
+
+ @Test
+ fun checkBoxTest_defaultSemantics() {
+ rule.setContent {
+ LightMaterialTheme {
+ Column {
+ Checkbox(false, {}, modifier = Modifier.testTag("checkboxUnchecked"))
+ Checkbox(true, {}, modifier = Modifier.testTag("checkboxChecked"))
+ }
+ }
+ }
+
+ rule.onNodeWithTag("checkboxUnchecked")
+ .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Checkbox))
+ .assertIsEnabled()
+ .assertIsOff()
+
+ rule.onNodeWithTag("checkboxChecked")
+ .assert(SemanticsMatcher.expectValue(SemanticsProperties.Role, Role.Checkbox))
+ .assertIsEnabled()
+ .assertIsOn()
+ }
+
+ @Test
+ fun checkBoxTest_toggle() {
+ rule.setContent {
+ LightMaterialTheme {
+ val (checked, onCheckedChange) = remember { mutableStateOf(false) }
+ Checkbox(checked, onCheckedChange, modifier = Modifier.testTag(defaultTag))
+ }
+ }
+
+ rule.onNodeWithTag(defaultTag)
+ .assertIsOff()
+ .performClick()
+ .assertIsOn()
+ }
+
+ @Test
+ fun checkBoxTest_toggle_twice() {
+ rule.setContent {
+ LightMaterialTheme {
+ val (checked, onCheckedChange) = remember { mutableStateOf(false) }
+ Checkbox(checked, onCheckedChange, modifier = Modifier.testTag(defaultTag))
+ }
+ }
+
+ rule.onNodeWithTag(defaultTag)
+ .assertIsOff()
+ .performClick()
+ .assertIsOn()
+ .performClick()
+ .assertIsOff()
+ }
+
+ @Test
+ fun checkBoxTest_untoggleable_whenEmptyLambda() {
+ val parentTag = "parent"
+
+ rule.setContent {
+ LightMaterialTheme {
+ val (checked, _) = remember { mutableStateOf(false) }
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(parentTag)) {
+ Checkbox(
+ checked,
+ {},
+ enabled = false,
+ modifier = Modifier
+ .testTag(defaultTag)
+ .semantics { focused = true }
+ )
+ }
+ }
+ }
+
+ rule.onNodeWithTag(defaultTag)
+ .assertHasClickAction()
+
+ // Check not merged into parent
+ rule.onNodeWithTag(parentTag)
+ .assert(isNotFocusable())
+ }
+
+ @Test
+ fun checkBoxTest_untoggleableAndMergeable_whenNullLambda() {
+ rule.setContent {
+ LightMaterialTheme {
+ val (checked, _) = remember { mutableStateOf(false) }
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(defaultTag)) {
+ Checkbox(
+ checked,
+ null,
+ modifier = Modifier.semantics { focused = true }
+ )
+ }
+ }
+ }
+
+ rule.onNodeWithTag(defaultTag)
+ .assertHasNoClickAction()
+ .assert(isFocusable()) // Check merged into parent
+ }
+}
\ No newline at end of file
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt
index 9267ce5..19df4f2 100644
--- a/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/MaterialThemeCommon.kt
@@ -17,6 +17,7 @@
package androidx.tv.material3
import androidx.compose.runtime.Composable
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
@@ -33,3 +34,21 @@
content()
}
}
+
+/**
+ * Wraps Compose content in a [MaterialTheme].
+ *
+ * @param colorScheme a [ColorScheme] to provide to the theme. Usually a [lightColorScheme],
+ * [darkColorScheme], or a dynamic one
+ */
+@OptIn(ExperimentalTvMaterial3Api::class)
+fun ComposeContentTestRule.setMaterialContent(
+ colorScheme: ColorScheme,
+ content: @Composable () -> Unit
+) {
+ setContent {
+ MaterialTheme(colorScheme = colorScheme) {
+ content()
+ }
+ }
+}
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
new file mode 100644
index 0000000..960df60
--- /dev/null
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.tv.material3
+
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.snap
+import androidx.compose.animation.core.spring
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.selection.triStateToggleable
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.CornerRadius
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.PathMeasure
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.state.ToggleableState
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.lerp
+import androidx.tv.material3.tokens.CheckboxTokens
+import kotlin.math.floor
+import kotlin.math.max
+
+/**
+ * <a href="https://m3.material.io/components/checkbox/overview" class="external" target="_blank">Material Design checkbox</a>.
+ *
+ * Checkboxes allow users to select one or more items from a set. Checkboxes can turn an option on
+ * or off.
+ *
+ * ![Checkbox image](https://developer.android.com/images/reference/androidx/compose/material3/checkbox.png)
+ *
+ * @see [TriStateCheckbox] if you require support for an indeterminate state.
+ *
+ * @param checked whether this checkbox is checked or unchecked
+ * @param onCheckedChange called when this checkbox is clicked. If `null`, then this checkbox will
+ * not be interactable, unless something else handles its input events and updates its state.
+ * @param modifier the [Modifier] to be applied to this checkbox
+ * @param enabled controls the enabled state of this checkbox. When `false`, this component will not
+ * respond to user input, and it will appear visually disabled and disabled to accessibility
+ * services.
+ * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in
+ * different states. See [CheckboxDefaults.colors].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
+ * for this checkbox. You can create and pass in your own `remember`ed instance to observe
+ * [Interaction]s and customize the appearance / behavior of this checkbox in different states.
+ */
+@ExperimentalTvMaterial3Api
+@Composable
+fun Checkbox(
+ checked: Boolean,
+ onCheckedChange: ((Boolean) -> Unit)?,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ colors: CheckboxColors = CheckboxDefaults.colors(),
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+) {
+ TriStateCheckbox(
+ state = ToggleableState(checked),
+ onClick = if (onCheckedChange != null) {
+ { onCheckedChange(!checked) }
+ } else {
+ null
+ },
+ modifier = modifier,
+ enabled = enabled,
+ colors = colors,
+ interactionSource = interactionSource
+ )
+}
+
+/**
+ * <a href="https://m3.material.io/components/checkbox/guidelines" class="external" target="_blank">Material Design checkbox</a> parent.
+ *
+ * Checkboxes can have a parent-child relationship with other checkboxes. When the parent checkbox
+ * is checked, all child checkboxes are checked. If a parent checkbox is unchecked, all child
+ * checkboxes are unchecked. If some, but not all, child checkboxes are checked, the parent checkbox
+ * becomes an indeterminate checkbox.
+ *
+ * ![Checkbox image](https://developer.android.com/images/reference/androidx/compose/material3/indeterminate-checkbox.png)
+ *
+ * @see [Checkbox] if you want a simple component that represents Boolean state
+ *
+ * @param state whether this checkbox is checked, unchecked, or in an indeterminate state
+ * @param onClick called when this checkbox is clicked. If `null`, then this checkbox will not be
+ * interactable, unless something else handles its input events and updates its [state].
+ * @param modifier the [Modifier] to be applied to this checkbox
+ * @param enabled controls the enabled state of this checkbox. When `false`, this component will not
+ * respond to user input, and it will appear visually disabled and disabled to accessibility
+ * services.
+ * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in
+ * different states. See [CheckboxDefaults.colors].
+ * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
+ * for this checkbox. You can create and pass in your own `remember`ed instance to observe
+ * [Interaction]s and customize the appearance / behavior of this checkbox in different states.
+ */
+@ExperimentalTvMaterial3Api
+@Composable
+fun TriStateCheckbox(
+ state: ToggleableState,
+ onClick: (() -> Unit)?,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ colors: CheckboxColors = CheckboxDefaults.colors(),
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+) {
+ val toggleableModifier =
+ if (onClick != null) {
+ Modifier.triStateToggleable(
+ state = state,
+ onClick = onClick,
+ enabled = enabled,
+ role = Role.Checkbox,
+ interactionSource = interactionSource,
+ indication = null
+ )
+ } else {
+ Modifier
+ }
+ CheckboxImpl(
+ enabled = enabled,
+ value = state,
+ modifier = modifier
+ .then(toggleableModifier)
+ .padding(CheckboxDefaultPadding),
+ colors = colors
+ )
+}
+
+/**
+ * Defaults used in [Checkbox] and [TriStateCheckbox].
+ */
+@ExperimentalTvMaterial3Api
+object CheckboxDefaults {
+ /**
+ * Creates a [CheckboxColors] that will animate between the provided colors according to the
+ * Material specification.
+ *
+ * @param checkedColor the color that will be used for the border and box when checked
+ * @param uncheckedColor color that will be used for the border when unchecked
+ * @param checkmarkColor color that will be used for the checkmark when checked
+ * @param disabledCheckedColor color that will be used for the box and border when disabled and
+ * checked
+ * @param disabledUncheckedColor color that will be used for the box and border when disabled
+ * and not checked
+ * @param disabledIndeterminateColor color that will be used for the box and
+ * border in a [TriStateCheckbox] when disabled AND in an [ToggleableState.Indeterminate] state.
+ */
+ @Composable
+ fun colors(
+ checkedColor: Color =
+ MaterialTheme.colorScheme.fromToken(CheckboxTokens.SelectedContainerColor),
+ uncheckedColor: Color =
+ MaterialTheme.colorScheme.fromToken(CheckboxTokens.UnselectedOutlineColor),
+ checkmarkColor: Color =
+ MaterialTheme.colorScheme.fromToken(CheckboxTokens.SelectedIconColor),
+ disabledCheckedColor: Color =
+ MaterialTheme.colorScheme
+ .fromToken(CheckboxTokens.SelectedDisabledContainerColor)
+ .copy(alpha = CheckboxTokens.SelectedDisabledContainerOpacity),
+ disabledUncheckedColor: Color =
+ MaterialTheme.colorScheme
+ .fromToken(CheckboxTokens.UnselectedDisabledOutlineColor)
+ .copy(alpha = CheckboxTokens.UnselectedDisabledContainerOpacity),
+ disabledIndeterminateColor: Color = disabledCheckedColor
+ ): CheckboxColors = CheckboxColors(
+ checkedBorderColor = checkedColor,
+ checkedBoxColor = checkedColor,
+ checkedCheckmarkColor = checkmarkColor,
+ uncheckedCheckmarkColor = checkmarkColor.copy(alpha = 0f),
+ uncheckedBoxColor = checkedColor.copy(alpha = 0f),
+ disabledCheckedBoxColor = disabledCheckedColor,
+ disabledUncheckedBoxColor = disabledUncheckedColor.copy(alpha = 0f),
+ disabledIndeterminateBoxColor = disabledIndeterminateColor,
+ uncheckedBorderColor = uncheckedColor,
+ disabledBorderColor = disabledCheckedColor,
+ disabledIndeterminateBorderColor = disabledIndeterminateColor,
+ )
+}
+
+@OptIn(ExperimentalTvMaterial3Api::class)
+@Composable
+private fun CheckboxImpl(
+ enabled: Boolean,
+ value: ToggleableState,
+ modifier: Modifier,
+ colors: CheckboxColors
+) {
+ val transition = updateTransition(value)
+ val checkDrawFraction = transition.animateFloat(
+ transitionSpec = {
+ when {
+ initialState == ToggleableState.Off -> tween(CheckAnimationDuration)
+ targetState == ToggleableState.Off -> snap(BoxOutDuration)
+ else -> spring()
+ }
+ }
+ ) {
+ when (it) {
+ ToggleableState.On -> 1f
+ ToggleableState.Off -> 0f
+ ToggleableState.Indeterminate -> 1f
+ }
+ }
+
+ val checkCenterGravitationShiftFraction = transition.animateFloat(
+ transitionSpec = {
+ when {
+ initialState == ToggleableState.Off -> snap()
+ targetState == ToggleableState.Off -> snap(BoxOutDuration)
+ else -> tween(durationMillis = CheckAnimationDuration)
+ }
+ }
+ ) {
+ when (it) {
+ ToggleableState.On -> 0f
+ ToggleableState.Off -> 0f
+ ToggleableState.Indeterminate -> 1f
+ }
+ }
+ val checkCache = remember { CheckDrawingCache() }
+ val checkColor = colors.checkmarkColor(value)
+ val boxColor = colors.boxColor(enabled, value)
+ val borderColor = colors.borderColor(enabled, value)
+ Canvas(
+ modifier
+ .wrapContentSize(Alignment.Center)
+ .requiredSize(CheckboxSize)
+ ) {
+ val strokeWidthPx = floor(StrokeWidth.toPx())
+ drawBox(
+ boxColor = boxColor.value,
+ borderColor = borderColor.value,
+ radius = RadiusSize.toPx(),
+ strokeWidth = strokeWidthPx
+ )
+ drawCheck(
+ checkColor = checkColor.value,
+ checkFraction = checkDrawFraction.value,
+ crossCenterGravitation = checkCenterGravitationShiftFraction.value,
+ strokeWidthPx = strokeWidthPx,
+ drawingCache = checkCache
+ )
+ }
+}
+
+private fun DrawScope.drawBox(
+ boxColor: Color,
+ borderColor: Color,
+ radius: Float,
+ strokeWidth: Float
+) {
+ val halfStrokeWidth = strokeWidth / 2.0f
+ val stroke = Stroke(strokeWidth)
+ val checkboxSize = size.width
+ if (boxColor == borderColor) {
+ drawRoundRect(
+ boxColor,
+ size = Size(checkboxSize, checkboxSize),
+ cornerRadius = CornerRadius(radius),
+ style = Fill
+ )
+ } else {
+ drawRoundRect(
+ boxColor,
+ topLeft = Offset(strokeWidth, strokeWidth),
+ size = Size(checkboxSize - strokeWidth * 2, checkboxSize - strokeWidth * 2),
+ cornerRadius = CornerRadius(max(0f, radius - strokeWidth)),
+ style = Fill
+ )
+ drawRoundRect(
+ borderColor,
+ topLeft = Offset(halfStrokeWidth, halfStrokeWidth),
+ size = Size(checkboxSize - strokeWidth, checkboxSize - strokeWidth),
+ cornerRadius = CornerRadius(radius - halfStrokeWidth),
+ style = stroke
+ )
+ }
+}
+
+private fun DrawScope.drawCheck(
+ checkColor: Color,
+ checkFraction: Float,
+ crossCenterGravitation: Float,
+ strokeWidthPx: Float,
+ drawingCache: CheckDrawingCache
+) {
+ val stroke = Stroke(width = strokeWidthPx, cap = StrokeCap.Square)
+ val width = size.width
+ val checkCrossX = 0.4f
+ val checkCrossY = 0.7f
+ val leftX = 0.2f
+ val leftY = 0.5f
+ val rightX = 0.8f
+ val rightY = 0.3f
+
+ val gravitatedCrossX = lerp(checkCrossX, 0.5f, crossCenterGravitation)
+ val gravitatedCrossY = lerp(checkCrossY, 0.5f, crossCenterGravitation)
+ // gravitate only Y for end to achieve center line
+ val gravitatedLeftY = lerp(leftY, 0.5f, crossCenterGravitation)
+ val gravitatedRightY = lerp(rightY, 0.5f, crossCenterGravitation)
+
+ with(drawingCache) {
+ checkPath.reset()
+ checkPath.moveTo(width * leftX, width * gravitatedLeftY)
+ checkPath.lineTo(width * gravitatedCrossX, width * gravitatedCrossY)
+ checkPath.lineTo(width * rightX, width * gravitatedRightY)
+ // TODO: replace with proper declarative non-android alternative when ready (b/158188351)
+ pathMeasure.setPath(checkPath, false)
+ pathToDraw.reset()
+ pathMeasure.getSegment(
+ 0f, pathMeasure.length * checkFraction, pathToDraw, true
+ )
+ }
+ drawPath(drawingCache.pathToDraw, checkColor, style = stroke)
+}
+
+@Immutable
+private class CheckDrawingCache(
+ val checkPath: Path = Path(),
+ val pathMeasure: PathMeasure = PathMeasure(),
+ val pathToDraw: Path = Path()
+)
+
+/**
+ * Represents the colors used by the three different sections (checkmark, box, and border) of a
+ * [Checkbox] or [TriStateCheckbox] in different states.
+ *
+ * See [CheckboxDefaults.colors] for the default implementation that follows Material
+ * specifications.
+ */
+@ExperimentalTvMaterial3Api
+@Immutable
+class CheckboxColors internal constructor(
+ private val checkedCheckmarkColor: Color,
+ private val uncheckedCheckmarkColor: Color,
+ private val checkedBoxColor: Color,
+ private val uncheckedBoxColor: Color,
+ private val disabledCheckedBoxColor: Color,
+ private val disabledUncheckedBoxColor: Color,
+ private val disabledIndeterminateBoxColor: Color,
+ private val checkedBorderColor: Color,
+ private val uncheckedBorderColor: Color,
+ private val disabledBorderColor: Color,
+ private val disabledIndeterminateBorderColor: Color
+) {
+ /**
+ * Represents the color used for the checkmark inside the checkbox, depending on [state].
+ *
+ * @param state the [ToggleableState] of the checkbox
+ */
+ @Composable
+ internal fun checkmarkColor(state: ToggleableState): State<Color> {
+ val target = if (state == ToggleableState.Off) {
+ uncheckedCheckmarkColor
+ } else {
+ checkedCheckmarkColor
+ }
+
+ val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
+ return animateColorAsState(target, tween(durationMillis = duration))
+ }
+
+ /**
+ * Represents the color used for the box (background) of the checkbox, depending on [enabled]
+ * and [state].
+ *
+ * @param enabled whether the checkbox is enabled or not
+ * @param state the [ToggleableState] of the checkbox
+ */
+ @Composable
+ internal fun boxColor(enabled: Boolean, state: ToggleableState): State<Color> {
+ val target = if (enabled) {
+ when (state) {
+ ToggleableState.On, ToggleableState.Indeterminate -> checkedBoxColor
+ ToggleableState.Off -> uncheckedBoxColor
+ }
+ } else {
+ when (state) {
+ ToggleableState.On -> disabledCheckedBoxColor
+ ToggleableState.Indeterminate -> disabledIndeterminateBoxColor
+ ToggleableState.Off -> disabledUncheckedBoxColor
+ }
+ }
+
+ // If not enabled 'snap' to the disabled state, as there should be no animations between
+ // enabled / disabled.
+ return if (enabled) {
+ val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
+ animateColorAsState(target, tween(durationMillis = duration))
+ } else {
+ rememberUpdatedState(target)
+ }
+ }
+
+ /**
+ * Represents the color used for the border of the checkbox, depending on [enabled] and [state].
+ *
+ * @param enabled whether the checkbox is enabled or not
+ * @param state the [ToggleableState] of the checkbox
+ */
+ @Composable
+ internal fun borderColor(enabled: Boolean, state: ToggleableState): State<Color> {
+ val target = if (enabled) {
+ when (state) {
+ ToggleableState.On, ToggleableState.Indeterminate -> checkedBorderColor
+ ToggleableState.Off -> uncheckedBorderColor
+ }
+ } else {
+ when (state) {
+ ToggleableState.Indeterminate -> disabledIndeterminateBorderColor
+ ToggleableState.On, ToggleableState.Off -> disabledBorderColor
+ }
+ }
+
+ // If not enabled 'snap' to the disabled state, as there should be no animations between
+ // enabled / disabled.
+ return if (enabled) {
+ val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
+ animateColorAsState(target, tween(durationMillis = duration))
+ } else {
+ rememberUpdatedState(target)
+ }
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is CheckboxColors) return false
+
+ if (checkedCheckmarkColor != other.checkedCheckmarkColor) return false
+ if (uncheckedCheckmarkColor != other.uncheckedCheckmarkColor) return false
+ if (checkedBoxColor != other.checkedBoxColor) return false
+ if (uncheckedBoxColor != other.uncheckedBoxColor) return false
+ if (disabledCheckedBoxColor != other.disabledCheckedBoxColor) return false
+ if (disabledUncheckedBoxColor != other.disabledUncheckedBoxColor) return false
+ if (disabledIndeterminateBoxColor != other.disabledIndeterminateBoxColor) return false
+ if (checkedBorderColor != other.checkedBorderColor) return false
+ if (uncheckedBorderColor != other.uncheckedBorderColor) return false
+ if (disabledBorderColor != other.disabledBorderColor) return false
+ if (disabledIndeterminateBorderColor != other.disabledIndeterminateBorderColor) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = checkedCheckmarkColor.hashCode()
+ result = 31 * result + uncheckedCheckmarkColor.hashCode()
+ result = 31 * result + checkedBoxColor.hashCode()
+ result = 31 * result + uncheckedBoxColor.hashCode()
+ result = 31 * result + disabledCheckedBoxColor.hashCode()
+ result = 31 * result + disabledUncheckedBoxColor.hashCode()
+ result = 31 * result + disabledIndeterminateBoxColor.hashCode()
+ result = 31 * result + checkedBorderColor.hashCode()
+ result = 31 * result + uncheckedBorderColor.hashCode()
+ result = 31 * result + disabledBorderColor.hashCode()
+ result = 31 * result + disabledIndeterminateBorderColor.hashCode()
+ return result
+ }
+}
+
+private const val BoxInDuration = 50
+private const val BoxOutDuration = 100
+private const val CheckAnimationDuration = 100
+
+// TODO(b/188529841): Update the padding and size when the Checkbox spec is finalized.
+private val CheckboxDefaultPadding = 2.dp
+private val CheckboxSize = 20.dp
+private val StrokeWidth = 2.dp
+private val RadiusSize = 2.dp
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt
index 0b0626d..b6f5fda 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Indications.kt
@@ -61,9 +61,8 @@
* applied to. It takes in parameters like [Color], [Shape], blur radius, and Offset to let users
* customise it to their brand personality.
*/
-@ExperimentalTvMaterial3Api
@Stable
-class GlowIndication(
+internal class GlowIndication(
private val color: Color,
private val shape: Shape,
private val glowBlurRadius: Dp,
@@ -84,7 +83,6 @@
}
}
-@ExperimentalTvMaterial3Api
private class GlowIndicationInstance(
color: Color,
private val shape: Shape,
@@ -154,9 +152,9 @@
* @param offsetY describes the vertical offset of the glow from the composable.
* @return A remembered instance of [GlowIndication].
*/
-@ExperimentalTvMaterial3Api
+@OptIn(ExperimentalTvMaterial3Api::class)
@Composable
-fun rememberGlowIndication(
+internal fun rememberGlowIndication(
color: Color = MaterialTheme.colorScheme.primaryContainer,
shape: Shape = RectangleShape,
glowBlurRadius: Dp = 0.dp,
@@ -181,9 +179,8 @@
* it's being applied to.
* @param inset describes the offset of the border from the composable it's being applied to.
*/
-@ExperimentalTvMaterial3Api
@Immutable
-class BorderIndication(
+internal class BorderIndication(
private val brush: Brush,
private val width: Dp,
private val shape: Shape,
@@ -195,6 +192,7 @@
* @param border the [androidx.tv.material3.Border] instance that is used to create and return
* an [BorderIndication] instance
*/
+ @OptIn(ExperimentalTvMaterial3Api::class)
constructor(border: Border) :
this(
brush = border.border.brush,
@@ -262,9 +260,8 @@
* ScaleIndication is an [Indication] that scales the composable by the provided factor. This
* indication by default will create a smooth animation between the state changes.
*/
-@ExperimentalTvMaterial3Api
@Stable
-class ScaleIndication(private val scale: Float) : Indication {
+internal class ScaleIndication(private val scale: Float) : Indication {
@Composable
override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
val interaction by interactionSource.interactions.collectAsState(
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/tokens/CheckboxTokens.kt b/tv/tv-material/src/main/java/androidx/tv/material3/tokens/CheckboxTokens.kt
new file mode 100644
index 0000000..3bd10be
--- /dev/null
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/tokens/CheckboxTokens.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// VERSION: v0_001 (Inspired by androidx.compose.material3.tokens v0_103)
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+package androidx.tv.material3.tokens
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.ui.unit.dp
+
+internal object CheckboxTokens {
+ val ContainerHeight = 18.0.dp
+ val ContainerShape = RoundedCornerShape(2.0.dp)
+ val ContainerWidth = 18.0.dp
+ val IconSize = 18.0.dp
+ val SelectedContainerColor = ColorSchemeKeyTokens.Primary
+ val SelectedDisabledContainerColor = ColorSchemeKeyTokens.OnSurface
+ const val SelectedDisabledContainerOpacity = 0.38f
+ val SelectedDisabledContainerOutlineWidth = 0.0.dp
+ val SelectedDisabledIconColor = ColorSchemeKeyTokens.Surface
+ val SelectedErrorContainerColor = ColorSchemeKeyTokens.Error
+ val SelectedErrorFocusContainerColor = ColorSchemeKeyTokens.Error
+ val SelectedErrorFocusIconColor = ColorSchemeKeyTokens.OnError
+ val SelectedErrorFocusOutlineWidth = 0.0.dp
+ val SelectedErrorHoverContainerColor = ColorSchemeKeyTokens.Error
+ val SelectedErrorHoverIconColor = ColorSchemeKeyTokens.OnError
+ val SelectedErrorHoverOutlineWidth = 0.0.dp
+ val SelectedErrorIconColor = ColorSchemeKeyTokens.OnError
+ val SelectedErrorPressedContainerColor = ColorSchemeKeyTokens.Error
+ val SelectedErrorPressedIconColor = ColorSchemeKeyTokens.OnError
+ val SelectedErrorPressedOutlineWidth = 0.0.dp
+ val SelectedFocusContainerColor = ColorSchemeKeyTokens.Primary
+ val SelectedFocusIconColor = ColorSchemeKeyTokens.OnPrimary
+ val SelectedFocusOutlineWidth = 0.0.dp
+ val SelectedHoverContainerColor = ColorSchemeKeyTokens.Primary
+ val SelectedHoverIconColor = ColorSchemeKeyTokens.OnPrimary
+ val SelectedHoverOutlineWidth = 0.0.dp
+ val SelectedIconColor = ColorSchemeKeyTokens.OnPrimary
+ val SelectedOutlineWidth = 0.0.dp
+ val SelectedPressedContainerColor = ColorSchemeKeyTokens.Primary
+ val SelectedPressedIconColor = ColorSchemeKeyTokens.OnPrimary
+ val SelectedPressedOutlineWidth = 0.0.dp
+ val StateLayerShape = ShapeKeyTokens.CornerFull
+ val StateLayerSize = 40.0.dp
+ const val UnselectedDisabledContainerOpacity = 0.38f
+ val UnselectedDisabledOutlineColor = ColorSchemeKeyTokens.OnSurface
+ val UnselectedDisabledOutlineWidth = 2.0.dp
+ val UnselectedErrorFocusOutlineColor = ColorSchemeKeyTokens.Error
+ val UnselectedErrorFocusOutlineWidth = 2.0.dp
+ val UnselectedErrorHoverOutlineColor = ColorSchemeKeyTokens.Error
+ val UnselectedErrorHoverOutlineWidth = 2.0.dp
+ val UnselectedErrorOutlineColor = ColorSchemeKeyTokens.Error
+ val UnselectedErrorPressedOutlineColor = ColorSchemeKeyTokens.Error
+ val UnselectedErrorPressedOutlineWidth = 2.0.dp
+ val UnselectedFocusOutlineColor = ColorSchemeKeyTokens.OnSurface
+ val UnselectedFocusOutlineWidth = 2.0.dp
+ val UnselectedHoverOutlineColor = ColorSchemeKeyTokens.OnSurface
+ val UnselectedHoverOutlineWidth = 2.0.dp
+ val UnselectedOutlineColor = ColorSchemeKeyTokens.OnSurfaceVariant
+ val UnselectedOutlineWidth = 2.0.dp
+ val UnselectedPressedOutlineColor = ColorSchemeKeyTokens.OnSurface
+ val UnselectedPressedOutlineWidth = 2.0.dp
+}
diff --git a/wear/compose/OWNERS b/wear/compose/OWNERS
index f346c9b..b369ef6 100644
--- a/wear/compose/OWNERS
+++ b/wear/compose/OWNERS
@@ -1,3 +1,4 @@
# Bug component: 1077984
jnichol@google.com
stevebower@google.com
+ssancho@google.com
diff --git a/wear/compose/compose-foundation/api/api_lint.ignore b/wear/compose/compose-foundation/api/api_lint.ignore
new file mode 100644
index 0000000..edcb394
--- /dev/null
+++ b/wear/compose/compose-foundation/api/api_lint.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.wear.compose.foundation.lazy.ScalingLazyListState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.foundation.lazy.ScalingLazyListState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field ExpandableState.expanded:
+ Invalid name for boolean property `expanded`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ScalingLazyListLayoutInfo.reverseLayout:
+ Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/compose/compose-material/api/api_lint.ignore b/wear/compose/compose-material/api/api_lint.ignore
new file mode 100644
index 0000000..6051f9d
--- /dev/null
+++ b/wear/compose/compose-material/api/api_lint.ignore
@@ -0,0 +1,13 @@
+// Baseline format: 1.0
+GetterSetterNames: androidx.wear.compose.material.PickerState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.material.PickerState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.material.ScalingLazyListState#getCanScrollBackward():
+ Getter for boolean property `canScrollBackward` is named `getCanScrollBackward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: androidx.wear.compose.material.ScalingLazyListState#getCanScrollForward():
+ Getter for boolean property `canScrollForward` is named `getCanScrollForward` but should match the property name. Use `@get:JvmName` to rename.
+GetterSetterNames: field PickerState.repeatItems:
+ Invalid name for boolean property `repeatItems`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ScalingLazyListLayoutInfo.reverseLayout:
+ Invalid name for boolean property `reverseLayout`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/compose/compose-material/api/public_plus_experimental_current.txt b/wear/compose/compose-material/api/public_plus_experimental_current.txt
index 3dd2192..fb0f899 100644
--- a/wear/compose/compose-material/api/public_plus_experimental_current.txt
+++ b/wear/compose/compose-material/api/public_plus_experimental_current.txt
@@ -633,13 +633,13 @@
}
@androidx.compose.runtime.Immutable @androidx.wear.compose.material.ExperimentalWearMaterialApi public final class SwipeProgress<T> {
- ctor public SwipeProgress(T? from, T? to, float fraction);
+ ctor public SwipeProgress(T from, T to, float fraction);
method public float getFraction();
- method public T! getFrom();
- method public T! getTo();
+ method public T getFrom();
+ method public T getTo();
property public final float fraction;
- property public final T! from;
- property public final T! to;
+ property public final T from;
+ property public final T to;
}
public final class SwipeToDismissBoxDefaults {
@@ -699,9 +699,9 @@
}
@androidx.compose.runtime.Stable @androidx.wear.compose.material.ExperimentalWearMaterialApi public class SwipeableState<T> {
- ctor public SwipeableState(T? initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
- method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? animateTo(T? targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method public final T! getCurrentValue();
+ ctor public SwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
+ method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ method public final T getCurrentValue();
method public final float getDirection();
method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
method public final androidx.compose.runtime.State<java.lang.Float> getOverflow();
@@ -709,8 +709,8 @@
method public final T! getTargetValue();
method public final boolean isAnimationRunning();
method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? snapTo(T? targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
- property public final T! currentValue;
+ method @androidx.wear.compose.material.ExperimentalWearMaterialApi public final suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+ property public final T currentValue;
property @androidx.wear.compose.material.ExperimentalWearMaterialApi public final float direction;
property public final boolean isAnimationRunning;
property @androidx.wear.compose.material.ExperimentalWearMaterialApi public final androidx.compose.runtime.State<java.lang.Float> offset;
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
index 934752c..c0dfbe8 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
@@ -74,14 +74,14 @@
Chip(
onClick = {},
colors = ChipDefaults.primaryChipColors(),
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").assertExists()
+ rule.onNodeWithTag(TEST_TAG).assertExists()
}
@Test
@@ -91,14 +91,14 @@
onClick = {},
colors = ChipDefaults.primaryChipColors(),
enabled = true,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").assertHasClickAction()
+ rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
}
@Test
@@ -108,14 +108,14 @@
onClick = {},
colors = ChipDefaults.primaryChipColors(),
enabled = false,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").assertHasClickAction()
+ rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
}
@Test
@@ -125,14 +125,14 @@
onClick = {},
colors = ChipDefaults.primaryChipColors(),
enabled = true,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").assertIsEnabled()
+ rule.onNodeWithTag(TEST_TAG).assertIsEnabled()
}
@Test
@@ -142,14 +142,14 @@
onClick = {},
colors = ChipDefaults.primaryChipColors(),
enabled = false,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").assertIsNotEnabled()
+ rule.onNodeWithTag(TEST_TAG).assertIsNotEnabled()
}
@Test
@@ -161,14 +161,14 @@
onClick = { clicked = true },
colors = ChipDefaults.primaryChipColors(),
enabled = true,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").performClick()
+ rule.onNodeWithTag(TEST_TAG).performClick()
rule.runOnIdle {
assertEquals(true, clicked)
@@ -184,14 +184,14 @@
onClick = { clicked = true },
colors = ChipDefaults.primaryChipColors(),
enabled = false,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item").performClick()
+ rule.onNodeWithTag(TEST_TAG).performClick()
rule.runOnIdle {
assertEquals(false, clicked)
@@ -205,14 +205,59 @@
onClick = {},
colors = ChipDefaults.primaryChipColors(),
enabled = false,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
) {
TestImage()
}
}
- rule.onNodeWithTag("test-item")
+ rule.onNodeWithTag(TEST_TAG)
+ .assert(
+ SemanticsMatcher.expectValue(
+ SemanticsProperties.Role,
+ Role.Button
+ )
+ )
+ }
+
+ @Test
+ fun has_role_button_for_three_slot_chip() {
+ rule.setContentWithTheme {
+ Chip(
+ onClick = {},
+ label = {},
+ secondaryLabel = {},
+ icon = { TestImage() },
+ colors = ChipDefaults.primaryChipColors(),
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG),
+ )
+ }
+
+ rule.onNodeWithTag(TEST_TAG)
+ .assert(
+ SemanticsMatcher.expectValue(
+ SemanticsProperties.Role,
+ Role.Button
+ )
+ )
+ }
+
+ @Test
+ fun has_role_button_for_compact_chip() {
+ rule.setContentWithTheme {
+ CompactChip(
+ onClick = {},
+ label = {},
+ icon = { TestImage() },
+ colors = ChipDefaults.primaryChipColors(),
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG),
+ )
+ }
+
+ rule.onNodeWithTag(TEST_TAG)
.assert(
SemanticsMatcher.expectValue(
SemanticsProperties.Role,
@@ -225,7 +270,7 @@
fun is_stadium_shape_under_ltr() =
rule.isStadiumShape(LayoutDirection.Ltr) {
Chip(
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder(),
onClick = {},
colors = ChipDefaults.primaryChipColors(),
@@ -236,7 +281,7 @@
fun is_stadium_shape_under_rtl() =
rule.isStadiumShape(LayoutDirection.Rtl) {
Chip(
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder(),
onClick = {},
colors = ChipDefaults.primaryChipColors(),
@@ -612,13 +657,13 @@
content = {},
colors = ChipDefaults.primaryChipColors(backgroundColor = overrideColor),
enabled = true,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
}
- rule.onNodeWithTag("test-item")
+ rule.onNodeWithTag(TEST_TAG)
.captureToImage()
.assertContainsColor(overrideColor, 50.0f)
}
@@ -634,13 +679,13 @@
content = {},
colors = ChipDefaults.chipColors(disabledBackgroundColor = overrideColor),
enabled = false,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
}
- rule.onNodeWithTag("test-item")
+ rule.onNodeWithTag(TEST_TAG)
.captureToImage()
.assertContainsColor(overrideColor, 50.0f)
}
@@ -659,7 +704,7 @@
actualContentColor = LocalContentColor.current
},
enabled = true,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
@@ -687,7 +732,7 @@
actualSecondaryContentColor = LocalContentColor.current
},
enabled = true,
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
}
assertEquals(expectedContent, actualContentColor)
@@ -714,7 +759,7 @@
actualIconColor = LocalContentColor.current
},
enabled = true,
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
}
assertEquals(expectedContent, actualContentColor)
@@ -735,7 +780,7 @@
actualContentColor = LocalContentColor.current
},
enabled = false,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
@@ -768,7 +813,7 @@
colors = testChipColors.chipColors(),
content = { actualContent = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
@@ -819,7 +864,7 @@
colors = testChipColors.chipColors(),
label = { actualContent = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
} else {
@@ -828,7 +873,7 @@
colors = testChipColors.chipColors(),
content = { actualContent = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
@@ -837,7 +882,7 @@
assertEquals(expectedContent, actualContent)
- rule.onNodeWithTag("test-item")
+ rule.onNodeWithTag(TEST_TAG)
.captureToImage()
.assertContainsColor(
if (expectedBackground != Color.Transparent) expectedBackground else testBackground,
@@ -898,7 +943,7 @@
label = { actualContent = LocalContentColor.current },
icon = { actualIcon = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
} else {
Chip(
@@ -908,7 +953,7 @@
secondaryLabel = { actualSecondaryContent = LocalContentColor.current },
icon = { actualIcon = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
}
}
@@ -920,7 +965,7 @@
}
assertEquals(expectedIcon, actualIcon)
- rule.onNodeWithTag("test-item")
+ rule.onNodeWithTag(TEST_TAG)
.captureToImage()
.assertContainsColor(
if (expectedBackground != Color.Transparent) expectedBackground else testBackground,
@@ -967,7 +1012,7 @@
label = { actualContent = LocalContentColor.current },
icon = { actualIcon = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
} else {
Chip(
@@ -977,7 +1022,7 @@
secondaryLabel = { actualSecondaryContent = LocalContentColor.current },
icon = { actualIcon = LocalContentColor.current },
enabled = status.enabled(),
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
}
}
@@ -1008,7 +1053,7 @@
actualTextStyle = LocalTextStyle.current
},
enabled = true,
- modifier = Modifier.testTag("test-item"),
+ modifier = Modifier.testTag(TEST_TAG),
border = ChipDefaults.chipBorder()
)
}
@@ -1034,7 +1079,7 @@
actualSecondaryLabelTextStyle = LocalTextStyle.current
},
enabled = true,
- modifier = Modifier.testTag("test-item")
+ modifier = Modifier.testTag(TEST_TAG)
)
}
assertEquals(expectedTextStyle, actualLabelTextStyle)
@@ -1116,12 +1161,12 @@
chipColor = MaterialTheme.colors.primary
content(
Modifier
- .testTag("test-item")
+ .testTag(TEST_TAG)
.padding(padding)
.background(background))
}
- rule.onNodeWithTag("test-item")
+ rule.onNodeWithTag(TEST_TAG)
.captureToImage()
.assertShape(
density = rule.density,
@@ -1165,7 +1210,7 @@
}
}
- onNodeWithTag("test-item")
+ onNodeWithTag(TEST_TAG)
.captureToImage()
.assertShape(
density = density,
diff --git a/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt b/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt
index e1b7374..ae59fc3 100644
--- a/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt
+++ b/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/Resources.android.kt
@@ -20,13 +20,19 @@
import android.text.format.DateFormat
import android.view.Surface
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
@Composable
-internal actual fun isRoundDevice(): Boolean = LocalConfiguration.current.isScreenRound
+internal actual fun isRoundDevice(): Boolean {
+ val configuration = LocalConfiguration.current
+ return remember(configuration) {
+ configuration.isScreenRound
+ }
+}
@Composable
internal actual fun imageResource(image: ImageResources): Painter =
@@ -45,12 +51,16 @@
internal actual fun currentTimeMillis(): Long = System.currentTimeMillis()
@Composable
-internal actual fun isLeftyModeEnabled() =
- Settings.System.getInt(
- LocalContext.current.contentResolver,
- Settings.System.USER_ROTATION,
- Surface.ROTATION_0
- ) == Surface.ROTATION_180
+internal actual fun isLeftyModeEnabled(): Boolean {
+ val context = LocalContext.current
+ return remember(context) {
+ Settings.System.getInt(
+ context.contentResolver,
+ Settings.System.USER_ROTATION,
+ Surface.ROTATION_0
+ ) == Surface.ROTATION_180
+ }
+}
@Composable
internal actual fun screenHeightDp() = LocalContext.current.resources.configuration.screenHeightDp
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
index d426bb2..2408507 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Chip.kt
@@ -362,7 +362,7 @@
shape = shape,
border = { border.borderStroke(enabled = it) },
defaultIconSpacing = ChipDefaults.IconSpacing,
- role = null
+ role = Role.Button
)
}
@@ -646,7 +646,7 @@
defaultIconOnlyCompactChipWidth = ChipDefaults.IconOnlyCompactChipWidth,
defaultCompactChipTapTargetPadding = ChipDefaults.CompactChipTapTargetPadding,
defaultIconSpacing = ChipDefaults.IconSpacing,
- role = null,
+ role = Role.Button,
)
}
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
index 424101c..3f9434c 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
@@ -20,16 +20,16 @@
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
import androidx.wear.compose.foundation.lazy.ScalingLazyListItemInfo as ScalingLazyListItemInfo
import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType as ScalingLazyListAnchorType
-import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.AnimationVector
import androidx.compose.animation.core.AnimationVector2D
import androidx.compose.animation.core.CubicBezierEasing
+import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.TwoWayConverter
+import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
@@ -38,6 +38,7 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
@@ -50,6 +51,7 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.AbsoluteAlignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
@@ -488,27 +490,29 @@
)
}
- AnimatedVisibility(
- visible = actuallyVisible.value,
- enter = fadeIn(),
- exit = fadeOut()
+ // Using same animation spec as AnimatedVisibility's fadeIn and fadeOut
+ val positionIndicatorAlpha by animateFloatAsState(
+ targetValue = if (actuallyVisible.value) 1f else 0f,
+ spring(stiffness = Spring.StiffnessMediumLow)
+ )
+
+ BoundsLimiter(boundsOffset, boundsSize, modifier, onSizeChanged = {
+ containerSize = it
+ }
) {
- BoundsLimiter(boundsOffset, boundsSize, modifier, onSizeChanged = {
- containerSize = it
- }
- ) {
- Box(
- modifier = Modifier
+ Box(
+ modifier = Modifier
.fillMaxSize()
+ .alpha(positionIndicatorAlpha)
.drawWithContent {
// We need to invert reverseDirection when the screen is round and we are on
// the left.
- val actualReverseDirection =
- if (isScreenRound && !indicatorOnTheRight) {
- !reverseDirection
- } else {
- reverseDirection
- }
+ val actualReverseDirection =
+ if (isScreenRound && !indicatorOnTheRight) {
+ !reverseDirection
+ } else {
+ reverseDirection
+ }
val indicatorPosition = if (actualReverseDirection) {
1 - animatedDisplayState.value.position
@@ -520,12 +524,13 @@
// We want position = 0 be the indicator aligned at the top of its area and
// position = 1 be aligned at the bottom of the area.
- val indicatorStart =
- indicatorPosition * (1 - animatedDisplayState.value.size)
+ val indicatorStart =
+ indicatorPosition * (1 - animatedDisplayState.value.size)
- val diameter = max(containerSize.width, containerSize.height)
+ val diameter = max(containerSize.width, containerSize.height)
val paddingHorizontalPx = paddingHorizontal.toPx()
+
if (isScreenRound) {
val usableHalf = diameter / 2f - paddingHorizontalPx
val sweepDegrees =
@@ -556,8 +561,7 @@
)
}
}
- )
- }
+ )
}
}
@@ -596,10 +600,30 @@
return animatable.asState()
}
+@Immutable
internal class DisplayState(
val position: Float,
val size: Float
-)
+) {
+ override fun hashCode(): Int {
+ var result = position.hashCode()
+ result = 31 * result + size.hashCode()
+ return result
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null) return false
+ if (this::class != other::class) return false
+
+ other as DisplayState
+
+ if (position != other.position) return false
+ if (size != other.size) return false
+
+ return true
+ }
+}
internal val DisplayStateTwoWayConverter: TwoWayConverter<DisplayState, AnimationVector2D> =
TwoWayConverter(
diff --git a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
index d3ad096..ede1df5 100644
--- a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
+++ b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/ButtonTest.kt
@@ -198,6 +198,28 @@
}
@Test
+ fun has_role_button_for_three_slot_chip() {
+ rule.setContentWithTheme {
+ Button(
+ onClick = {},
+ label = {},
+ secondaryLabel = {},
+ icon = { TestImage() },
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG),
+ )
+ }
+
+ rule.onNodeWithTag(TEST_TAG)
+ .assert(
+ SemanticsMatcher.expectValue(
+ SemanticsProperties.Role,
+ Role.Button
+ )
+ )
+ }
+
+ @Test
fun gives_base_button_correct_text_style() {
var actualTextStyle = TextStyle.Default
var expectedTextStyle = TextStyle.Default
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
index b21f208..74f1a4c 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
@@ -19,15 +19,11 @@
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
-import android.view.MotionEvent
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
import androidx.annotation.RequiresApi
import androidx.compose.foundation.focusable
-import androidx.compose.foundation.gestures.FlingBehavior
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
@@ -44,6 +40,7 @@
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
+import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -54,15 +51,11 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
-import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.focused
@@ -526,21 +519,26 @@
fontSize = with(LocalDensity.current) { 34.dp.toSp() }
)
)
- val touchExplorationServicesEnabled by DefaultTouchExplorationStateProvider()
+ val touchExplorationStateProvider = remember { DefaultTouchExplorationStateProvider() }
+ val touchExplorationServicesEnabled by touchExplorationStateProvider
.touchExplorationState()
MaterialTheme(typography = typography) {
- var focusedElement by remember {
- mutableStateOf(
- if (touchExplorationServicesEnabled)
- FocusableElementDatePicker.NONE else FocusableElementDatePicker.DAY
- )
+ // When the time picker loads, none of the individual pickers are selected in talkback mode,
+ // otherwise day picker should be focused.
+ val pickerGroupState = if (touchExplorationServicesEnabled) {
+ rememberPickerGroupState(FocusableElementDatePicker.NONE.index)
+ } else {
+ rememberPickerGroupState(FocusableElementDatePicker.DAY.index)
}
- val focusRequesterDay = remember { FocusRequester() }
- val focusRequesterMonth = remember { FocusRequester() }
- val focusRequesterYear = remember { FocusRequester() }
+ val textStyle = MaterialTheme.typography.display3
+ val optionColor = MaterialTheme.colors.secondary
val focusRequesterConfirmButton = remember { FocusRequester() }
+ val yearString = "Year"
+ val monthString = "Month"
+ val dayString = "Day"
+
LaunchedEffect(
datePickerState.yearState.selectedOption,
datePickerState.monthState.selectedOption
@@ -557,62 +555,45 @@
}
val shortMonthNames = remember { getMonthNames("MMM") }
val fullMonthNames = remember { getMonthNames("MMMM") }
- val yearContentDescription by remember(focusedElement, datePickerState.currentYear()) {
+ val yearContentDescription by remember(
+ pickerGroupState.selectedIndex,
+ datePickerState.currentYear()
+ ) {
derivedStateOf {
createDescriptionDatePicker(
- focusedElement,
+ pickerGroupState,
datePickerState.currentYear(),
- "${datePickerState.currentYear()}"
+ yearString
)
}
}
- val monthContentDescription by remember(focusedElement, datePickerState.currentMonth()) {
+ val monthContentDescription by remember(
+ pickerGroupState.selectedIndex,
+ datePickerState.currentMonth()
+ ) {
derivedStateOf {
- createDescriptionDatePicker(
- focusedElement,
- datePickerState.currentMonth(),
+ if (pickerGroupState.selectedIndex == FocusableElementDatePicker.NONE.index) {
+ monthString
+ } else {
fullMonthNames[(datePickerState.currentMonth() - 1) % 12]
- )
- } }
- val dayContentDescription by remember(focusedElement, datePickerState.currentDay()) {
- derivedStateOf {
- createDescriptionDatePicker(
- focusedElement, datePickerState.currentDay(), "${datePickerState.currentDay()}"
- )
- } }
-
- val focusManager = LocalFocusManager.current
-
- LaunchedEffect(focusedElement) {
- when (focusedElement) {
- FocusableElementDatePicker.DAY -> focusRequesterDay.requestFocus()
- FocusableElementDatePicker.MONTH -> focusRequesterMonth.requestFocus()
- FocusableElementDatePicker.YEAR -> focusRequesterYear.requestFocus()
- else -> focusManager.clearFocus()
+ }
}
}
-
+ val dayContentDescription by remember(
+ pickerGroupState.selectedIndex,
+ datePickerState.currentDay()
+ ) {
+ derivedStateOf {
+ createDescriptionDatePicker(
+ pickerGroupState,
+ datePickerState.currentDay(),
+ dayString
+ )
+ }
+ }
BoxWithConstraints(
modifier = modifier
.fillMaxSize()
- .then(
- if (touchExplorationServicesEnabled) {
- when (focusedElement) {
- FocusableElementDatePicker.DAY ->
- Modifier.scrollablePicker(datePickerState.dayState)
-
- FocusableElementDatePicker.MONTH ->
- Modifier.scrollablePicker(datePickerState.monthState)
-
- FocusableElementDatePicker.YEAR ->
- Modifier.scrollablePicker(datePickerState.yearState)
-
- else -> Modifier
- }
- } else {
- Modifier
- }
- )
) {
val boxConstraints = this
Column(
@@ -621,15 +602,15 @@
) {
Spacer(Modifier.height(16.dp))
Text(
- text = when (focusedElement) {
- FocusableElementDatePicker.DAY -> "Day"
- FocusableElementDatePicker.MONTH -> "Month"
- FocusableElementDatePicker.YEAR -> "Year"
+ text = when (FocusableElementDatePicker[pickerGroupState.selectedIndex]) {
+ FocusableElementDatePicker.DAY -> dayString
+ FocusableElementDatePicker.MONTH -> monthString
+ FocusableElementDatePicker.YEAR -> yearString
else -> ""
},
- color = MaterialTheme.colors.secondary,
+ color = optionColor,
style = MaterialTheme.typography.button,
- maxLines = 1,
+ maxLines = 1
)
val weightsToCenterVertically = 0.5f
Spacer(
@@ -640,84 +621,86 @@
val spacerWidth = 8.dp
val dayWidth = 54.dp
val monthWidth = 80.dp
- val yearWidth = 128.dp
- val doubleTapToNext = {
- position: FocusableElementDatePicker, next: FocusableElementDatePicker ->
- focusedElement = when (focusedElement) {
- position -> next
- else -> position
+ val yearWidth = 100.dp
+ val numberOfSpacers = 2
+ val onPickerSelected =
+ { current: FocusableElementDatePicker, next: FocusableElementDatePicker ->
+ if (pickerGroupState.selectedIndex != current.index) {
+ pickerGroupState.selectedIndex = current.index
+ } else {
+ pickerGroupState.selectedIndex = next.index
+ if (next == FocusableElementDatePicker.CONFIRM_BUTTON) {
+ focusRequesterConfirmButton.requestFocus()
+ }
}
}
- val offset = when (focusedElement) {
- FocusableElementDatePicker.DAY -> (boxConstraints.maxWidth - dayWidth) / 2
- FocusableElementDatePicker.MONTH ->
- (boxConstraints.maxWidth - monthWidth) / 2 - dayWidth - spacerWidth
- FocusableElementDatePicker.NONE -> (boxConstraints.maxWidth - dayWidth) / 2
- else -> (boxConstraints.maxWidth - yearWidth) / 2 - monthWidth
- }
+
Row(
modifier = Modifier
.fillMaxWidth()
- .offset(offset)
+ .offset(
+ getPickerGroupRowOffset(
+ boxConstraints.maxWidth,
+ dayWidth,
+ monthWidth,
+ yearWidth,
+ spacerWidth,
+ numberOfSpacers,
+ touchExplorationServicesEnabled,
+ pickerGroupState
+ )
+ ),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.Center
) {
- if (focusedElement.index < 2) {
- DatePickerImpl(
- state = datePickerState.dayState,
- readOnly = focusedElement != FocusableElementDatePicker.DAY,
+ PickerGroup(
+ pickerGroupItemWithRSB(
+ pickerState = datePickerState.dayState,
+ modifier = Modifier.size(dayWidth, 100.dp),
+ contentDescription = dayContentDescription,
onSelected = {
- doubleTapToNext(
+ onPickerSelected(
FocusableElementDatePicker.DAY,
FocusableElementDatePicker.MONTH
)
},
- text = { day: Int -> "%d".format(datePickerState.currentDay(day)) },
- width = dayWidth,
- focusRequester = focusRequesterDay,
- contentDescription = dayContentDescription,
- userScrollEnabled = !touchExplorationServicesEnabled ||
- focusedElement == FocusableElementDatePicker.DAY,
- touchExplorationServicesEnabled = touchExplorationServicesEnabled
- )
- Spacer(modifier = Modifier.width(spacerWidth))
- }
- DatePickerImpl(
- state = datePickerState.monthState,
- readOnly = focusedElement != FocusableElementDatePicker.MONTH,
- onSelected = {
- doubleTapToNext(
- FocusableElementDatePicker.MONTH,
- FocusableElementDatePicker.YEAR
- )
- },
- text = { month: Int ->
- shortMonthNames[(datePickerState.currentMonth(month) - 1) % 12] },
- width = monthWidth,
- focusRequester = focusRequesterMonth,
- contentDescription = monthContentDescription,
- userScrollEnabled = !touchExplorationServicesEnabled ||
- focusedElement == FocusableElementDatePicker.MONTH,
- touchExplorationServicesEnabled = touchExplorationServicesEnabled
- )
- if (focusedElement.index > 0) {
- Spacer(modifier = Modifier.width(spacerWidth))
- DatePickerImpl(
- state = datePickerState.yearState,
- readOnly = focusedElement != FocusableElementDatePicker.YEAR,
+ option = pickerTextOption(textStyle) {
+ "%d".format(datePickerState.currentDay(it))
+ }
+ ),
+ pickerGroupItemWithRSB(
+ pickerState = datePickerState.monthState,
+ modifier = Modifier.size(monthWidth, 100.dp),
onSelected = {
- doubleTapToNext(
+ onPickerSelected(
+ FocusableElementDatePicker.MONTH,
+ FocusableElementDatePicker.YEAR
+ )
+ },
+ contentDescription = monthContentDescription,
+ option = pickerTextOption(textStyle) {
+ shortMonthNames[(datePickerState.currentMonth(it) - 1) % 12]
+ }
+ ),
+ pickerGroupItemWithRSB(
+ pickerState = datePickerState.yearState,
+ modifier = Modifier.size(yearWidth, 100.dp),
+ onSelected = {
+ onPickerSelected(
FocusableElementDatePicker.YEAR,
FocusableElementDatePicker.CONFIRM_BUTTON
)
},
- text = { year: Int -> "%4d".format(datePickerState.currentYear(year)) },
- width = yearWidth,
- focusRequester = focusRequesterYear,
contentDescription = yearContentDescription,
- userScrollEnabled = !touchExplorationServicesEnabled ||
- focusedElement == FocusableElementDatePicker.YEAR,
- touchExplorationServicesEnabled = touchExplorationServicesEnabled
- )
- }
+ option = pickerTextOption(textStyle) {
+ "%4d".format(datePickerState.currentYear(it))
+ }
+ ),
+ pickerGroupState = pickerGroupState,
+ autoCenter = true,
+ separator = { Spacer(modifier = Modifier.width(spacerWidth)) },
+ touchExplorationStateProvider = touchExplorationStateProvider
+ )
}
Spacer(
Modifier
@@ -726,20 +709,22 @@
)
Button(
onClick = {
- if (focusedElement.index >= 2) {
+ if (pickerGroupState.selectedIndex >= 2) {
val confirmedYear: Int = datePickerState.currentYear()
val confirmedMonth: Int = datePickerState.currentMonth()
val confirmedDay: Int = datePickerState.currentDay()
val confirmedDate =
LocalDate.of(confirmedYear, confirmedMonth, confirmedDay)
onDateConfirm(confirmedDate)
- } else if (focusedElement == FocusableElementDatePicker.DAY) {
- doubleTapToNext(
+ } else if (pickerGroupState.selectedIndex ==
+ FocusableElementDatePicker.DAY.index) {
+ onPickerSelected(
FocusableElementDatePicker.DAY,
FocusableElementDatePicker.MONTH
)
- } else if (focusedElement == FocusableElementDatePicker.MONTH) {
- doubleTapToNext(
+ } else if (pickerGroupState.selectedIndex ==
+ FocusableElementDatePicker.MONTH.index) {
+ onPickerSelected(
FocusableElementDatePicker.MONTH,
FocusableElementDatePicker.YEAR
)
@@ -747,17 +732,22 @@
},
modifier = Modifier
.semantics {
- focused = focusedElement == FocusableElementDatePicker.CONFIRM_BUTTON
+ focused = pickerGroupState.selectedIndex ==
+ FocusableElementDatePicker.CONFIRM_BUTTON.index
}
.focusRequester(focusRequesterConfirmButton)
+ .focusable()
) {
- DemoIcon(
- resourceId =
- if (focusedElement.index < 2) R.drawable.ic_chevron_right_24
- else R.drawable.ic_check_24px,
- contentDescription =
- if (focusedElement.index >= 2) "confirm"
- else "next"
+ Icon(
+ imageVector = if (pickerGroupState.selectedIndex < 2)
+ Icons.Filled.KeyboardArrowRight else Icons.Filled.Check,
+ contentDescription = if (pickerGroupState.selectedIndex < 2)
+ "next"
+ else
+ "confirm",
+ modifier = Modifier
+ .size(24.dp)
+ .wrapContentSize(align = Alignment.Center)
)
}
Spacer(Modifier.height(12.dp))
@@ -766,67 +756,37 @@
}
}
-@Composable
-private fun DatePickerImpl(
- state: PickerState,
- readOnly: Boolean,
- onSelected: () -> Unit,
- text: (option: Int) -> String,
- focusRequester: FocusRequester,
- width: Dp,
- contentDescription: String,
- userScrollEnabled: Boolean,
- touchExplorationServicesEnabled: Boolean
-) {
- PickerWithRSB(
- readOnly = readOnly,
- state = state,
- focusRequester = focusRequester,
- modifier = Modifier.size(width, 100.dp),
- onSelected = onSelected,
- contentDescription = contentDescription,
- userScrollEnabled = userScrollEnabled
- ) { option ->
- TimePiece(
- selected = !readOnly,
- onSelected = onSelected,
- text = text(option),
- style = MaterialTheme.typography.display2,
- touchExplorationServicesEnabled = touchExplorationServicesEnabled
- )
- }
-}
+// getPickerGroupRowOffset function calculates the offset of the picker group row in talkback mode.
+// Autocenter doesn't work when no index is selected which is the case in talkback mode.
+// Offset is required to move the first picker to the center.
+private fun getPickerGroupRowOffset(
+ rowWidth: Dp,
+ dayPickerWidth: Dp,
+ monthPickerWidth: Dp,
+ yearPickerWidth: Dp,
+ spacerWidth: Dp,
+ numberOfSpacers: Int,
+ touchExplorationServicesEnabled: Boolean,
+ pickerGroupState: PickerGroupState
+): Dp {
+ // Calculates the extra offset named currentOffset because the total content width is more than the screen width
+ var finalRowOffset = 0.dp
+ val totalContentWidth =
+ (dayPickerWidth + monthPickerWidth + yearPickerWidth + (spacerWidth * numberOfSpacers))
+ val currentOffset = (rowWidth - totalContentWidth) / 2
-// This is a demo file, suppressing the annotation group error.
-@SuppressLint("NullAnnotationGroup")
-@OptIn(ExperimentalComposeUiApi::class)
-@Composable
-internal fun TimePiece(
- selected: Boolean,
- onSelected: () -> Unit,
- text: String,
- style: TextStyle,
- touchExplorationServicesEnabled: Boolean = false
-) {
- Box(modifier = Modifier.fillMaxSize()) {
- val modifier = Modifier
- .align(Alignment.Center)
- .wrapContentSize()
- Text(
- text = text,
- maxLines = 1,
- style = style,
- color =
- if (selected) MaterialTheme.colors.secondary
- else MaterialTheme.colors.onBackground,
- modifier =
- if (selected || touchExplorationServicesEnabled) modifier
- else modifier.pointerInteropFilter {
- if (it.action == MotionEvent.ACTION_DOWN) onSelected()
- true
- },
- )
+ if (touchExplorationServicesEnabled &&
+ pickerGroupState.selectedIndex < 0 // When talkback is on and no picker is selected
+ ) {
+ finalRowOffset = ((rowWidth - dayPickerWidth) / 2) - currentOffset
+ } else if (touchExplorationServicesEnabled &&
+ pickerGroupState.selectedIndex > 2 // When talkback is on and focus goes to confirm button
+ ) {
+ finalRowOffset = ((rowWidth - yearPickerWidth) / 2) -
+ (dayPickerWidth + monthPickerWidth + (spacerWidth * numberOfSpacers) + currentOffset)
}
+
+ return finalRowOffset
}
@Composable
@@ -862,38 +822,6 @@
)
@Composable
-fun PickerWithRSB(
- state: PickerState,
- readOnly: Boolean,
- modifier: Modifier,
- focusRequester: FocusRequester,
- contentDescription: String?,
- readOnlyLabel: @Composable (BoxScope.() -> Unit)? = null,
- userScrollEnabled: Boolean = true,
- flingBehavior: FlingBehavior = PickerDefaults.flingBehavior(state = state),
- onSelected: () -> Unit = {},
- option: @Composable PickerScope.(optionIndex: Int) -> Unit
-) {
- Picker(
- state = state,
- modifier = if (userScrollEnabled) {
- modifier.rsbScroll(
- scrollableState = state,
- flingBehavior = flingBehavior,
- focusRequester = focusRequester,
- )
- } else modifier,
- flingBehavior = flingBehavior,
- readOnly = readOnly,
- readOnlyLabel = readOnlyLabel,
- userScrollEnabled = userScrollEnabled,
- onSelected = onSelected,
- contentDescription = contentDescription,
- option = option
- )
-}
-
-@Composable
fun PickerWithoutGradient() {
val items = listOf("One", "Two", "Three", "Four", "Five")
val state = rememberPickerState(items.size)
@@ -934,17 +862,6 @@
}
}
-private fun Modifier.scrollablePicker(
- pickerState: PickerState
-) = Modifier.composed {
- this.scrollable(
- state = pickerState,
- orientation = Orientation.Vertical,
- flingBehavior = PickerDefaults.flingBehavior(state = pickerState),
- reverseDirection = true
- )
-}
-
private fun createDescription(
pickerGroupState: PickerGroupState,
selectedValue: Int,
@@ -976,18 +893,13 @@
}
private fun createDescriptionDatePicker(
- focusedElement: FocusableElementDatePicker,
+ pickerGroupState: PickerGroupState,
selectedValue: Int,
label: String
): String {
- return when (focusedElement) {
- FocusableElementDatePicker.DAY -> {
- "$selectedValue"
- }
- FocusableElementDatePicker.YEAR -> {
- "$selectedValue"
- }
- else -> label
+ return when (pickerGroupState.selectedIndex) {
+ FocusableElementDatePicker.NONE.index -> label
+ else -> "$label, $selectedValue"
}
}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto b/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto
index 5dc5751..2a15694 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dimension.proto
@@ -150,9 +150,9 @@
}
}
-// A dimension that can be applied to a VendorExtension element.
-message VendorExtensionDimension {
- oneof inner {
+// A dimension that can be applied to a ExtensionLayoutElement element.
+message ExtensionDimension {
+ oneof inner {
DpProp linear_dimension = 1;
}
}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
index 1403194..db32f5c 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
@@ -47,8 +47,8 @@
// Font variant suited for body text.
FONT_VARIANT_BODY = 2;
- // Font variant suited for Vendor specified use.
- FONT_VARIANT_VENDOR_1 = 3;
+ // Placeholder for a custom font variant in the renderer.
+ FONT_VARIANT_EXTENSION_1 = 3;
}
// An extensible FontVariant property.
@@ -657,28 +657,30 @@
BoolProp rotate_contents = 2;
}
-// A layout element which can be defined by a vendor renderer extension. The
-// payload in this message will be passed verbatim to any registered vendor
-// extension in the layout renderer. It is then expected that the extension can
+// A layout element which can be defined by a renderer extension. The
+// payload in this message will be passed verbatim to any registered renderer
+// extension in the renderer. It is then expected that the extension can
// parse this message, and emit the relevant element.
//
-// If a vendor extension is not installed, this resource will not render
+// If a renderer extension is not installed, this resource will not render
// any element, although the specified space will still be occupied. If the
-// payload cannot be parsed by the vendor extension, then still nothing should
-// be rendered, although this behaviour is defined by the vendor extension.
-message VendorExtension {
- // The content of the vendor extension. This can be any data; it is expected
- // that the vendor extension knows how to parse this field.
+// payload cannot be parsed by the renderer extension, then still nothing should
+// be rendered, although this behaviour is defined by the renderer extension.
+message ExtensionLayoutElement {
+
+ // The content of the renderer extension element. This can be any data; it is
+ // expected that the renderer extension knows how to parse this field.
bytes payload = 1;
- // The Vendor ID that this extension is for.
- string vendor_id = 2;
+ // The ID of the renderer extension that should be used for rendering this
+ // layout element.
+ string extension_id = 2;
// The width of this element.
- VendorExtensionDimension width = 3;
+ ExtensionDimension width = 3;
// The height of this element.
- VendorExtensionDimension height = 4;
+ ExtensionDimension height = 4;
}
// The root of all layout elements. This exists to act as a holder for all of
@@ -693,7 +695,8 @@
Image image = 6;
Arc arc = 7;
Spannable spannable = 8;
- VendorExtension vendor_extension = 1000;
+
+ ExtensionLayoutElement extension = 1000;
}
}
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
index bc82951..de2ee97 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
@@ -3151,7 +3151,7 @@
nodePosId,
pipelineMaker);
break;
- case VENDOR_EXTENSION:
+ case EXTENSION:
// TODO(b/276703002): Add support for vendor extension.
break;
case INNER_NOT_SET:
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
index 404813e..f97ed264 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
@@ -89,8 +89,14 @@
* can be selected using this field.
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
- @IntDef({FONT_VARIANT_UNDEFINED, FONT_VARIANT_TITLE, FONT_VARIANT_BODY})
+ @IntDef({
+ FONT_VARIANT_UNDEFINED,
+ FONT_VARIANT_TITLE,
+ FONT_VARIANT_BODY,
+ FONT_VARIANT_CUSTOM_1
+ })
@Retention(RetentionPolicy.SOURCE)
+ @OptIn(markerClass = ProtoLayoutExperimental.class)
public @interface FontVariant {}
/** Font variant is undefined. */
@@ -102,6 +108,13 @@
/** Font variant suited for body text. */
public static final int FONT_VARIANT_BODY = 2;
+ /** Renderer dependent Font variant. If not supported, will behave similar to
+ * {@link #FONT_VARIANT_UNDEFINED}.
+ */
+ @ProtoLayoutExperimental
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ public static final int FONT_VARIANT_CUSTOM_1 = 3;
+
/**
* The alignment of a {@link SpanImage} within the line height of the surrounding {@link
* Spannable}.
diff --git a/wear/tiles/tiles/api/current.txt b/wear/tiles/tiles/api/current.txt
index beab05b..45fe573 100644
--- a/wear/tiles/tiles/api/current.txt
+++ b/wear/tiles/tiles/api/current.txt
@@ -250,35 +250,43 @@
}
public static final class EventBuilders.TileAddEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileAddEvent.Builder {
ctor public EventBuilders.TileAddEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileAddEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileEnterEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileEnterEvent.Builder {
ctor public EventBuilders.TileEnterEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileEnterEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileLeaveEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileLeaveEvent.Builder {
ctor public EventBuilders.TileLeaveEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileLeaveEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileRemoveEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileRemoveEvent.Builder {
ctor public EventBuilders.TileRemoveEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileRemoveEvent.Builder setTileId(int);
}
@Deprecated public final class LayoutElementBuilders {
@@ -873,6 +881,7 @@
method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
method public java.util.List<java.lang.String!> getResourceIds();
+ method public int getTileId();
method public String getVersion();
}
@@ -882,6 +891,7 @@
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+ method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setTileId(int);
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
}
@@ -890,6 +900,7 @@
method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
method @Deprecated public androidx.wear.tiles.StateBuilders.State? getState();
+ method public int getTileId();
}
public static final class RequestBuilders.TileRequest.Builder {
@@ -899,6 +910,7 @@
method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+ method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setTileId(int);
}
@Deprecated public final class ResourceBuilders {
diff --git a/wear/tiles/tiles/api/public_plus_experimental_current.txt b/wear/tiles/tiles/api/public_plus_experimental_current.txt
index 1a18796..0b4241a 100644
--- a/wear/tiles/tiles/api/public_plus_experimental_current.txt
+++ b/wear/tiles/tiles/api/public_plus_experimental_current.txt
@@ -250,35 +250,43 @@
}
public static final class EventBuilders.TileAddEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileAddEvent.Builder {
ctor public EventBuilders.TileAddEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileAddEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileEnterEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileEnterEvent.Builder {
ctor public EventBuilders.TileEnterEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileEnterEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileLeaveEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileLeaveEvent.Builder {
ctor public EventBuilders.TileLeaveEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileLeaveEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileRemoveEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileRemoveEvent.Builder {
ctor public EventBuilders.TileRemoveEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileRemoveEvent.Builder setTileId(int);
}
@Deprecated public final class LayoutElementBuilders {
@@ -889,6 +897,7 @@
method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
method public java.util.List<java.lang.String!> getResourceIds();
+ method public int getTileId();
method public String getVersion();
}
@@ -898,6 +907,7 @@
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+ method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setTileId(int);
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
}
@@ -906,6 +916,7 @@
method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
method @Deprecated public androidx.wear.tiles.StateBuilders.State? getState();
+ method public int getTileId();
}
public static final class RequestBuilders.TileRequest.Builder {
@@ -915,6 +926,7 @@
method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+ method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setTileId(int);
}
@Deprecated public final class ResourceBuilders {
diff --git a/wear/tiles/tiles/api/restricted_current.txt b/wear/tiles/tiles/api/restricted_current.txt
index beab05b..45fe573 100644
--- a/wear/tiles/tiles/api/restricted_current.txt
+++ b/wear/tiles/tiles/api/restricted_current.txt
@@ -250,35 +250,43 @@
}
public static final class EventBuilders.TileAddEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileAddEvent.Builder {
ctor public EventBuilders.TileAddEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileAddEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileEnterEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileEnterEvent.Builder {
ctor public EventBuilders.TileEnterEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileEnterEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileLeaveEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileLeaveEvent.Builder {
ctor public EventBuilders.TileLeaveEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileLeaveEvent.Builder setTileId(int);
}
public static final class EventBuilders.TileRemoveEvent {
+ method public int getTileId();
}
public static final class EventBuilders.TileRemoveEvent.Builder {
ctor public EventBuilders.TileRemoveEvent.Builder();
method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+ method public androidx.wear.tiles.EventBuilders.TileRemoveEvent.Builder setTileId(int);
}
@Deprecated public final class LayoutElementBuilders {
@@ -873,6 +881,7 @@
method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
method public java.util.List<java.lang.String!> getResourceIds();
+ method public int getTileId();
method public String getVersion();
}
@@ -882,6 +891,7 @@
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+ method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setTileId(int);
method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
}
@@ -890,6 +900,7 @@
method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
method @Deprecated public androidx.wear.tiles.StateBuilders.State? getState();
+ method public int getTileId();
}
public static final class RequestBuilders.TileRequest.Builder {
@@ -899,6 +910,7 @@
method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+ method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setTileId(int);
}
@Deprecated public final class ResourceBuilders {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java
index 96a8f60..0d962f5 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/EventBuilders.java
@@ -37,6 +37,18 @@
this.mImpl = impl;
}
+
+ /**
+ * Gets the instance ID of the tile, allocated when the tile instance is added to the
+ * carousel. This ID will remain the same for this tile instance as long it is not removed
+ * from the carousel.
+ *
+ * @since 1.0
+ */
+ public int getTileId() {
+ return mImpl.getTileId();
+ }
+
/**
* Creates a new wrapper instance from the proto.
*
@@ -57,11 +69,11 @@
return mImpl;
}
- @Override
- @NonNull
- public String toString() {
- return "TileAddEvent{" + "}";
- }
+ @Override
+ @NonNull
+ public String toString() {
+ return "TileAddEvent{" + "tileId=" + getTileId() + "}";
+ }
/** Builder for {@link TileAddEvent} */
public static final class Builder {
@@ -70,6 +82,17 @@
public Builder() {}
+ /**
+ * Sets the ID of the tile added to the carousel.
+ *
+ * @since 1.0
+ */
+ @NonNull
+ public Builder setTileId(int tileId) {
+ mImpl.setTileId(tileId);
+ return this;
+ }
+
/** Builds an instance from accumulated values. */
@NonNull
public TileAddEvent build() {
@@ -91,6 +114,17 @@
}
/**
+ * Gets the instance ID of the tile, allocated when the tile instance is added to the
+ * carousel. This ID will remain the same for this tile instance as long it is not removed
+ * from the carousel.
+ *
+ * @since 1.0
+ */
+ public int getTileId() {
+ return mImpl.getTileId();
+ }
+
+ /**
* Creates a new wrapper instance from the proto.
*
*/
@@ -110,11 +144,11 @@
return mImpl;
}
- @Override
- @NonNull
- public String toString() {
- return "TileRemoveEvent{" + "}";
- }
+ @Override
+ @NonNull
+ public String toString() {
+ return "TileRemoveEvent{" + "tileId=" + getTileId() + "}";
+ }
/** Builder for {@link TileRemoveEvent} */
public static final class Builder {
@@ -123,6 +157,17 @@
public Builder() {}
+ /**
+ * Sets the ID of the tile removed from the carousel.
+ *
+ * @since 1.0
+ */
+ @NonNull
+ public Builder setTileId(int tileId) {
+ mImpl.setTileId(tileId);
+ return this;
+ }
+
/** Builds an instance from accumulated values. */
@NonNull
public TileRemoveEvent build() {
@@ -144,6 +189,17 @@
}
/**
+ * Gets the instance ID of the tile, allocated when the tile instance is added to the
+ * carousel. This ID will remain the same for this tile instance as long it is not removed
+ * from the carousel.
+ *
+ * @since 1.0
+ */
+ public int getTileId() {
+ return mImpl.getTileId();
+ }
+
+ /**
* Creates a new wrapper instance from the proto.
*
*/
@@ -163,11 +219,11 @@
return mImpl;
}
- @Override
- @NonNull
- public String toString() {
- return "TileEnterEvent{" + "}";
- }
+ @Override
+ @NonNull
+ public String toString() {
+ return "TileEnterEvent{" + "tileId=" + getTileId() + "}";
+ }
/** Builder for {@link TileEnterEvent} */
public static final class Builder {
@@ -176,6 +232,17 @@
public Builder() {}
+ /**
+ * Sets the ID of the entered tile.
+ *
+ * @since 1.0
+ */
+ @NonNull
+ public Builder setTileId(int tileId) {
+ mImpl.setTileId(tileId);
+ return this;
+ }
+
/** Builds an instance from accumulated values. */
@NonNull
public TileEnterEvent build() {
@@ -198,6 +265,17 @@
}
/**
+ * Gets the instance ID of the tile, allocated when the tile instance is added to the
+ * carousel. This ID will remain the same for this tile instance as long it is not removed
+ * from the carousel.
+ *
+ * @since 1.0
+ */
+ public int getTileId() {
+ return mImpl.getTileId();
+ }
+
+ /**
* Creates a new wrapper instance from the proto.
*
*/
@@ -220,7 +298,10 @@
@Override
@NonNull
public String toString() {
- return "TileLeaveEvent{" + "}";
+ return "TileLeaveEvent{"
+ + "tileId="
+ + getTileId()
+ + "}";
}
/** Builder for {@link TileLeaveEvent} */
@@ -230,6 +311,17 @@
public Builder() {}
+ /**
+ * Sets the ID of the tile.
+ *
+ * @since 1.0
+ */
+ @NonNull
+ public Builder setTileId(int tileId) {
+ mImpl.setTileId(tileId);
+ return this;
+ }
+
/** Builds an instance from accumulated values. */
@NonNull
public TileLeaveEvent build() {
diff --git a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java
index 00023c6..cde0e81 100644
--- a/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java
+++ b/wear/tiles/tiles/src/main/java/androidx/wear/tiles/RequestBuilders.java
@@ -76,6 +76,17 @@
}
/**
+ * Gets the instance ID of the tile being requested, allocated when the tile instance is
+ * added to the carousel. This ID will remain the same for this tile instance as long it
+ * is not removed from the carousel.
+ *
+ * @since 1.0
+ */
+ public int getTileId() {
+ return mImpl.getTileId();
+ }
+
+ /**
* Gets the {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
* describing the device requesting the tile update.
*
@@ -157,6 +168,17 @@
}
/**
+ * Sets the ID of the tile being requested.
+ *
+ * @since 1.0
+ */
+ @NonNull
+ public Builder setTileId(int tileId) {
+ mImpl.setTileId(tileId);
+ return this;
+ }
+
+ /**
* Sets a {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
* describing the device requesting the tile update.
*
@@ -252,6 +274,17 @@
}
/**
+ * Gets the instance ID of the tile for which resources are being requested, allocated when
+ * the tile instance is added to the carousel. This ID will remain the same for this tile
+ * instance as long it is not removed from the carousel.
+ *
+ * @since 1.0
+ */
+ public int getTileId() {
+ return mImpl.getTileId();
+ }
+
+ /**
* Gets the {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
* describing the device requesting the resources.
*
@@ -334,6 +367,17 @@
}
/**
+ * Sets the ID of the tile for which resources are being requested.
+ *
+ * @since 1.0
+ */
+ @NonNull
+ public Builder setTileId(int tileId) {
+ mImpl.setTileId(tileId);
+ return this;
+ }
+
+ /**
* Sets a {@link androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters} object
* describing the device requesting the resources.
*
diff --git a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java
index 8f414a4..4bd3db4 100644
--- a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java
+++ b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/TileServiceTest.java
@@ -194,6 +194,7 @@
shadowOf(Looper.getMainLooper()).idle();
expect.that(mFakeTileServiceController.get().mOnTileAddCalled).isTrue();
+ expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
}
@Test
@@ -206,6 +207,7 @@
shadowOf(Looper.getMainLooper()).idle();
expect.that(mFakeTileServiceController.get().mOnTileRemoveCalled).isTrue();
+ expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
}
@Test
@@ -218,6 +220,7 @@
shadowOf(Looper.getMainLooper()).idle();
expect.that(mFakeTileServiceController.get().mOnTileEnterCalled).isTrue();
+ expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
}
@Test
@@ -230,6 +233,23 @@
shadowOf(Looper.getMainLooper()).idle();
expect.that(mFakeTileServiceController.get().mOnTileLeaveCalled).isTrue();
+ expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
+ }
+
+ @Test
+ public void tileService_tileRequest_setsTileId() throws Exception {
+ mTileProviderServiceStub.onTileRequest(
+ TILE_ID,
+ new TileRequestData(
+ RequestProto.TileRequest.newBuilder()
+ .build()
+ .toByteArray(),
+ TileRequestData.VERSION_PROTOBUF),
+ mMockTileCallback);
+
+ shadowOf(Looper.getMainLooper()).idle();
+
+ expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
}
@Test
@@ -291,6 +311,23 @@
}
@Test
+ public void tileService_resourcesRequest_setsTileId() throws Exception {
+ // Resources request needs to have DeviceParameters least to fill in the default.
+ mTileProviderServiceStub.onResourcesRequest(
+ TILE_ID,
+ new ResourcesRequestData(
+ RequestProto.ResourcesRequest.newBuilder()
+ .build()
+ .toByteArray(),
+ ResourcesRequestData.VERSION_PROTOBUF),
+ mMockResourcesCallback);
+
+ shadowOf(Looper.getMainLooper()).idle();
+
+ expect.that(mFakeTileServiceController.get().mTileId).isEqualTo(TILE_ID);
+ }
+
+ @Test
public void tileService_resourcesRequest_defaultVersionIfNotSet() throws Exception {
// Resources request needs to have DeviceParameters least to fill in the default.
mTileProviderServiceStub.onResourcesRequest(
@@ -402,25 +439,30 @@
@Nullable TileRequest mTileRequestParams = null;
@Nullable ResourcesRequest mResourcesRequestParams = null;
@Nullable RuntimeException mRequestFailure = null;
+ int mTileId = -1;
@Override
protected void onTileAddEvent(@NonNull TileAddEvent requestParams) {
mOnTileAddCalled = true;
+ mTileId = requestParams.getTileId();
}
@Override
protected void onTileRemoveEvent(@NonNull TileRemoveEvent requestParams) {
mOnTileRemoveCalled = true;
+ mTileId = requestParams.getTileId();
}
@Override
protected void onTileEnterEvent(@NonNull TileEnterEvent requestParams) {
mOnTileEnterCalled = true;
+ mTileId = requestParams.getTileId();
}
@Override
protected void onTileLeaveEvent(@NonNull TileLeaveEvent requestParams) {
mOnTileLeaveCalled = true;
+ mTileId = requestParams.getTileId();
}
@Override
@@ -428,6 +470,7 @@
protected ListenableFuture<TileBuilders.Tile> onTileRequest(
@NonNull TileRequest requestParams) {
mTileRequestParams = requestParams;
+ mTileId = requestParams.getTileId();
if (mRequestFailure != null) {
return Futures.immediateFailedFuture(mRequestFailure);
}
@@ -439,6 +482,7 @@
protected ListenableFuture<Resources> onTileResourcesRequest(
@NonNull ResourcesRequest requestParams) {
mResourcesRequestParams = requestParams;
+ mTileId = requestParams.getTileId();
if (mRequestFailure != null) {
return Futures.immediateFailedFuture(mRequestFailure);
}
diff --git a/wear/watchface/watchface-client/api/api_lint.ignore b/wear/watchface/watchface-client/api/api_lint.ignore
index b09bed7..abc1577 100644
--- a/wear/watchface/watchface-client/api/api_lint.ignore
+++ b/wear/watchface/watchface-client/api/api_lint.ignore
@@ -1,3 +1,7 @@
// Baseline format: 1.0
-ListenerLast: androidx.wear.watchface.client.WatchFaceControlClient#getOrCreateInteractiveWatchFaceClient(String, androidx.wear.watchface.client.DeviceConfig, androidx.wear.watchface.client.WatchUiState, androidx.wear.watchface.style.UserStyleData, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>, java.util.concurrent.Executor, androidx.wear.watchface.client.WatchFaceControlClient.PreviewImageUpdateRequestedListener, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) parameter #7:
- Listeners should always be at end of argument list (method `getOrCreateInteractiveWatchFaceClient`)
+GetterSetterNames: field ComplicationSlotMetadata.fixedComplicationDataSource:
+ Invalid name for boolean property `fixedComplicationDataSource`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationSlotState.fixedComplicationDataSource:
+ Invalid name for boolean property `fixedComplicationDataSource`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field WatchUiState.inAmbientMode:
+ Invalid name for boolean property `inAmbientMode`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface-complications-data-source/api/api_lint.ignore b/wear/watchface/watchface-complications-data-source/api/api_lint.ignore
index 51e6476..399a31e 100644
--- a/wear/watchface/watchface-complications-data-source/api/api_lint.ignore
+++ b/wear/watchface/watchface-complications-data-source/api/api_lint.ignore
@@ -1,4 +1,8 @@
// Baseline format: 1.0
+GetterSetterNames: field ComplicationRequest.immediateResponseRequired:
+ Invalid name for boolean property `immediateResponseRequired`. Should start with one of `has`, `can`, `should`, `is`.
+
+
InvalidNullabilityOverride: androidx.wear.watchface.complications.datasource.ComplicationDataSourceService#onBind(android.content.Intent):
Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
InvalidNullabilityOverride: androidx.wear.watchface.complications.datasource.ComplicationDataSourceService#onBind(android.content.Intent) parameter #0:
diff --git a/wear/watchface/watchface-complications-data/api/api_lint.ignore b/wear/watchface/watchface-complications-data/api/api_lint.ignore
index 36ca3c6..6481583 100644
--- a/wear/watchface/watchface-complications-data/api/api_lint.ignore
+++ b/wear/watchface/watchface-complications-data/api/api_lint.ignore
@@ -1,4 +1,10 @@
// Baseline format: 1.0
+GetterSetterNames: field ColorRamp.interpolated:
+ Invalid name for boolean property `interpolated`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationData.tapActionLostDueToSerialization:
+ Invalid name for boolean property `tapActionLostDueToSerialization`. Should start with one of `has`, `can`, `should`, `is`.
+
+
MissingGetterMatchingBuilder: androidx.wear.watchface.complications.data.TimeDifferenceComplicationText.Builder#setDisplayAsNow(boolean):
androidx.wear.watchface.complications.data.TimeDifferenceComplicationText does not declare a `isDisplayAsNow()` method matching method androidx.wear.watchface.complications.data.TimeDifferenceComplicationText.Builder.setDisplayAsNow(boolean)
MissingGetterMatchingBuilder: androidx.wear.watchface.complications.data.TimeDifferenceComplicationText.Builder#setText(CharSequence):
diff --git a/wear/watchface/watchface-editor-guava/api/api_lint.ignore b/wear/watchface/watchface-editor-guava/api/api_lint.ignore
index 1276c29..493947c 100644
--- a/wear/watchface/watchface-editor-guava/api/api_lint.ignore
+++ b/wear/watchface/watchface-editor-guava/api/api_lint.ignore
@@ -5,3 +5,7 @@
Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
AsyncSuffixFuture: androidx.wear.watchface.editor.ListenableEditorSession.Companion#listenableCreateOnWatchEditorSession(androidx.activity.ComponentActivity):
Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
+
+
+GetterSetterNames: field ListenableEditorSession.commitChangesOnClose:
+ Invalid name for boolean property `commitChangesOnClose`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface-editor/api/api_lint.ignore b/wear/watchface/watchface-editor/api/api_lint.ignore
index d7ed79d..f504b74 100644
--- a/wear/watchface/watchface-editor/api/api_lint.ignore
+++ b/wear/watchface/watchface-editor/api/api_lint.ignore
@@ -7,3 +7,7 @@
Methods must not throw unchecked exceptions
BannedThrow: androidx.wear.watchface.editor.EditorSession.Companion#createOnWatchEditorSession(androidx.activity.ComponentActivity, kotlin.coroutines.Continuation<? super androidx.wear.watchface.editor.EditorSession>):
Methods must not throw unchecked exceptions
+
+
+GetterSetterNames: field EditorSession.commitChangesOnClose:
+ Invalid name for boolean property `commitChangesOnClose`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface-style/api/api_lint.ignore b/wear/watchface/watchface-style/api/api_lint.ignore
new file mode 100644
index 0000000..a8815f1
--- /dev/null
+++ b/wear/watchface/watchface-style/api/api_lint.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+GetterSetterNames: field UserStyleSetting.BooleanUserStyleSetting.BooleanOption.value:
+ Invalid name for boolean property `value`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/wear/watchface/watchface/api/api_lint.ignore b/wear/watchface/watchface/api/api_lint.ignore
index c4ab5b2..85d6935 100644
--- a/wear/watchface/watchface/api/api_lint.ignore
+++ b/wear/watchface/watchface/api/api_lint.ignore
@@ -1,4 +1,16 @@
// Baseline format: 1.0
+GetterSetterNames: field ComplicationSlot.enabled:
+ Invalid name for boolean property `enabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationSlot.fixedComplicationDataSource:
+ Invalid name for boolean property `fixedComplicationDataSource`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field ComplicationSlot.initiallyEnabled:
+ Invalid name for boolean property `initiallyEnabled`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field Renderer.CanvasRenderer.clearWithBackgroundTintBeforeRenderingHighlightLayer:
+ Invalid name for boolean property `clearWithBackgroundTintBeforeRenderingHighlightLayer`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field WatchFace.LegacyWatchFaceOverlayStyle.tapEventsAccepted:
+ Invalid name for boolean property `tapEventsAccepted`. Should start with one of `has`, `can`, `should`, `is`.
+
+
InvalidNullabilityOverride: androidx.wear.watchface.WatchFaceService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
Invalid nullability on parameter `fd` in method `dump`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
InvalidNullabilityOverride: androidx.wear.watchface.WatchFaceService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
diff --git a/wear/wear/api/api_lint.ignore b/wear/wear/api/api_lint.ignore
index 5be9b59..61244fa 100644
--- a/wear/wear/api/api_lint.ignore
+++ b/wear/wear/api/api_lint.ignore
@@ -25,6 +25,10 @@
Symmetric method for `isAutoPeekEnabled` must be named `setAutoPeekEnabled`; was `setIsAutoPeekEnabled`
GetterSetterNames: androidx.wear.widget.drawer.WearableDrawerView#setIsLocked(boolean):
Symmetric method for `isLocked` must be named `setLocked`; was `setIsLocked`
+GetterSetterNames: field AmbientLifecycleObserver.AmbientDetails.burnInProtectionRequired:
+ Invalid name for boolean property `burnInProtectionRequired`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field AmbientLifecycleObserver.AmbientDetails.deviceHasLowBitAmbient:
+ Invalid name for boolean property `deviceHasLowBitAmbient`. Should start with one of `has`, `can`, `should`, `is`.
InvalidNullabilityOverride: androidx.wear.widget.ArcLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
diff --git a/window/extensions/extensions/build.gradle b/window/extensions/extensions/build.gradle
index 8830606..279cbba 100644
--- a/window/extensions/extensions/build.gradle
+++ b/window/extensions/extensions/build.gradle
@@ -26,7 +26,7 @@
api(libs.kotlinStdlib)
implementation("androidx.annotation:annotation:1.6.0")
implementation("androidx.annotation:annotation-experimental:1.1.0")
- implementation("androidx.window.extensions.core:core:1.0.0-beta01")
+ implementation("androidx.window.extensions.core:core:1.0.0-rc01")
testImplementation(libs.robolectric)
testImplementation(libs.testExtJunit)
diff --git a/window/window/api/api_lint.ignore b/window/window/api/api_lint.ignore
new file mode 100644
index 0000000..24bf744
--- /dev/null
+++ b/window/window/api/api_lint.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+GetterSetterNames: field ActivityRule.alwaysExpand:
+ Invalid name for boolean property `alwaysExpand`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SplitAttributesCalculatorParams.areDefaultConstraintsSatisfied:
+ Invalid name for boolean property `areDefaultConstraintsSatisfied`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field SplitPairRule.clearTop:
+ Invalid name for boolean property `clearTop`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 32d38d8..4e4170e 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -49,9 +49,11 @@
implementation("androidx.collection:collection:1.1.0")
implementation("androidx.core:core:1.8.0")
- implementation("androidx.window.extensions.core:core:1.0.0-beta01")
+ def extensions_core_version = "androidx.window.extensions.core:core:1.0.0-rc01"
+ def extensions_version = "androidx.window.extensions:extensions:1.1.0-rc01"
+ implementation(extensions_core_version)
compileOnly(project(":window:sidecar:sidecar"))
- compileOnly("androidx.window.extensions:extensions:1.1.0-beta01")
+ compileOnly(extensions_version)
testImplementation(libs.testCore)
testImplementation(libs.testRunner)
@@ -61,9 +63,9 @@
testImplementation(libs.mockitoCore4)
testImplementation(libs.mockitoKotlin4)
testImplementation(libs.kotlinCoroutinesTest)
- testImplementation("androidx.window.extensions.core:core:1.0.0-beta01")
+ testImplementation(extensions_core_version)
testImplementation(compileOnly(project(":window:sidecar:sidecar")))
- testImplementation(compileOnly("androidx.window.extensions:extensions:1.1.0-beta01"))
+ testImplementation(compileOnly(extensions_version))
androidTestImplementation(libs.testCore)
androidTestImplementation(libs.kotlinTestJunit)
@@ -77,9 +79,9 @@
androidTestImplementation(libs.multidex)
androidTestImplementation(libs.truth)
androidTestImplementation(libs.junit) // Needed for Assert.assertThrows
- androidTestImplementation("androidx.window.extensions.core:core:1.0.0-beta01")
+ androidTestImplementation(extensions_core_version)
androidTestImplementation(compileOnly(project(":window:sidecar:sidecar")))
- androidTestImplementation(compileOnly("androidx.window.extensions:extensions:1.1.0-beta01"))
+ androidTestImplementation(compileOnly(extensions_version))
}
androidx {
diff --git a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
index fdc25a2..bc0dac5 100644
--- a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
+++ b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
@@ -101,7 +101,6 @@
*/
private fun hasValidVendorApiLevel2(): Boolean {
return hasValidVendorApiLevel1() &&
- isMethodWindowLayoutInfoListenerJavaConsumerUiContextValid() &&
isMethodWindowLayoutInfoListenerWindowConsumerValid()
}
@@ -179,24 +178,6 @@
}
}
- private fun isMethodWindowLayoutInfoListenerJavaConsumerUiContextValid(): Boolean {
- return validateReflection(
- "WindowLayoutComponent#addWindowLayoutInfoListener" +
- "(${Context::class.java.name}, $JAVA_CONSUMER) is not valid"
- ) {
- val consumerClass =
- consumerAdapter.consumerClassOrNull() ?: return@validateReflection false
- val windowLayoutComponent = windowLayoutComponentClass
- val addListenerMethod = windowLayoutComponent
- .getMethod(
- "addWindowLayoutInfoListener",
- Context::class.java,
- consumerClass
- )
- addListenerMethod.isPublic
- }
- }
-
private val windowExtensionsProviderClass: Class<*>
get() {
return loader.loadClass(WINDOW_EXTENSIONS_PROVIDER_CLASS)